摘要:在開始之前,他們不會等待最后一個功能完成。第一個函數完成后,它將運行第二個函數。回調的問題是它創建了一個名為的東西。該函數返回此對象。再次,讓我們嘗試按順序打印字母,,這被稱為承諾鏈。該功能與版本保持一致。
本文轉自作者Sandeep Dinesh的文章:Callbacks, Promises and Async/Await
假設你有一個函數可以在一段隨機的時間后打印一個字符串:
function printString(string){ setTimeout( () => { console.log(string) }, Math.floor(Math.random() * 100) + 1 ) }
讓我們嘗試按順序打印字母A,B,C:
function printAll(){ printString("A") printString("B") printString("C") } printAll()
每次調用printAll時,您會注意到A,B和C以不同的隨機順序打印!
這是因為這些函數是異步的。每個函數按順序執行,但每個函數都獨立于它自己的setTimeout。在開始之前,他們不會等待最后一個功能完成。
這非常煩人,所以讓我們用回調修復它。
Callbacks回調是傳遞給另一個函數的函數。第一個函數完成后,它將運行第二個函數。
function printString(string, callback){ setTimeout( () => { console.log(string) callback() }, Math.floor(Math.random() * 100) + 1 ) }
你可以看到,修改原始函數是非常容易的,可以使用回調。
再次,讓我們嘗試按順序打印字母A,B,C:
function printAll(){ printString("A", () => { printString("B", () => { printString("C", () => {}) }) }) } printAll()
嗯,代碼現在很丑陋,但至少它有效!每次調用printAll時,都會得到相同的結果。
回調的問題是它創建了一個名為“Callback Hell”的東西。基本上,你開始在函數內的函數內嵌套函數,并且開始變得非常難以閱讀代碼。
PromisePromise嘗試修復這個嵌套問題。讓我們改變我們的功能來使用Promises
function printString(string){ return new Promise((resolve, reject) => { setTimeout( () => { console.log(string) resolve() }, Math.floor(Math.random() * 100) + 1 ) }) }
你可以看到它看起來仍然非常相似。您將整個函數包裝在Promise中,而不是調用回調,而是調用resolve(如果出現錯誤則拒絕)。該函數返回此Promise對象。
再次,讓我們嘗試按順序打印字母A,B,C:
function printAll(){ printString("A") .then(() => { return printString("B") }) .then(() => { return printString("C") }) } printAll()
這被稱為承諾鏈。您可以看到代碼返回函數的結果(將是Promise),并將其發送到鏈中的下一個函數。
代碼不再嵌套,但看起來仍然很混亂!
通過使用箭頭函數的功能,我們可以刪除“包裝器”功能。代碼變得更清晰,但仍然有很多不必要的括號:
function printAll(){ printString("A") .then(() => printString("B")) .then(() => printString("C")) } printAll()Await
Await基本上是Promises的語法糖。它使您的異步代碼看起來更像是同步/過程代碼,人類更容易理解。
該PRINTSTRING功能不自許的版本在所有改變。
再次,讓我們嘗試按順序打印字母A,B,C:
async function printAll(){ await printString("A") await printString("B") await printString("C") } printAll()
是啊...。好多了!
您可能會注意到我們對包裝函數printAll使用“async”關鍵字。這讓我們的JavaScript知道我們正在使用async / await語法,如果你想使用Await,這是必要的。這意味著你不能在全球范圍內使用Await; 它總是需要一個包裝函數。大多數JavaScript代碼都在函數內部運行,因此這不是什么大問題。
等等,這里還有更多哦該PRINTSTRING函數不返回任何東西,是獨立的,所有我們關心的是順序。但是,如果您想獲取第一個函數的輸出,在第二個函數中執行某些操作,然后將其傳遞給第三個函數,該怎么辦?
我們不是每次都打印字符串,而是創建一個連接字符串并傳遞它的函數。
Callbacks這里是回調樣式:
function addString(previous, current, callback){ setTimeout( () => { callback((previous + " " + current)) }, Math.floor(Math.random() * 100) + 1 ) }
為了使用它:
function addAll(){ addString("", "A", result => { addString(result, "B", result => { addString(result, "C", result => { console.log(result) // Prints out " A B C" }) }) }) } addAll()
不太好。
Promises這是Promise風格:
function addString(previous, current){ return new Promise((resolve, reject) => { setTimeout( () => { resolve(previous + " " + current) }, Math.floor(Math.random() * 100) + 1 ) }) }
為了使用它:
function addAll(){ addString("", "A") .then(result => { return addString(result, "B") }) .then(result => { return addString(result, "C") }) .then(result => { console.log(result) // Prints out " A B C" }) } addAll()
使用箭頭函數意味著我們可以使代碼更好一些:
function addAll(){ addString("", "A") .then(result => addString(result, "B")) .then(result => addString(result, "C")) .then(result => { console.log(result) // Prints out " A B C" }) } addAll()
這肯定更具可讀性,特別是如果你向鏈添加更多,但仍然是一堆括號。
Await該功能與Promise版本保持一致。
并且為了使用它:
async function addAll(){ let toPrint = "" toPrint = await addString(toPrint, "A") toPrint = await addString(toPrint, "B") toPrint = await addString(toPrint, "C") console.log(toPrint) // Prints out " A B C" } addAll()
Yeah. SO MUCH BETTER~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101638.html
摘要:控制臺將顯示回調地獄通常,回調只能由一個異步函數調用。更多資源使更友好規范使用異步函數簡化異步編碼旅程異步編程是一項在中無法避免的挑戰。 JavaScript經常聲稱是_異步_。那是什么意思?它如何影響發展?近年來這種方法有何變化? 請思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數語言都處理每...
摘要:控制臺將顯示回調地獄通常,回調只能由一個異步函數調用。更多資源使更友好規范使用異步函數簡化異步編碼旅程異步編程是一項在中無法避免的挑戰。 JavaScript經常聲稱是_異步_。那是什么意思?它如何影響發展?近年來這種方法有何變化? 請思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數語言都處理每...
摘要:控制臺將顯示回調地獄通常,回調只能由一個異步函數調用。更多資源使更友好規范使用異步函數簡化異步編碼旅程異步編程是一項在中無法避免的挑戰。 JavaScript經常聲稱是_異步_。那是什么意思?它如何影響發展?近年來這種方法有何變化? 請思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數語言都處理每...
摘要:讓我們使用它從數組中返回一個值數組在中,我們可以這樣做,這是一種更簡單的方法最重要的部分是創建數組,該數組立即調用所有的我們在主函數中等待這些。所以在我們真正等待完成之前,主函數就退出了。 原文:https://pouchdb.com/2015/03/0... PouchDB最棘手的方面之一是它的API是異步的。在Stack Overflow、Github和IRC上,我看到了不少困惑的...
摘要: async can be transformed to promise. So, if we want to understand async, we have to understand promise first. Promise Normally, promise is easy to understand, especially when using like this: p...
閱讀 1938·2021-11-24 09:39
閱讀 3278·2021-09-22 14:58
閱讀 1162·2019-08-30 15:54
閱讀 3315·2019-08-29 11:33
閱讀 1788·2019-08-26 13:54
閱讀 1598·2019-08-26 13:35
閱讀 2468·2019-08-23 18:14
閱讀 762·2019-08-23 17:04