摘要:在開(kāi)始之前,他們不會(huì)等待最后一個(gè)功能完成。第一個(gè)函數(shù)完成后,它將運(yùn)行第二個(gè)函數(shù)?;卣{(diào)的問(wèn)題是它創(chuàng)建了一個(gè)名為的東西。該函數(shù)返回此對(duì)象。再次,讓我們嘗試按順序打印字母,,這被稱(chēng)為承諾鏈。該功能與版本保持一致。
本文轉(zhuǎn)自作者Sandeep Dinesh的文章:Callbacks, Promises and Async/Await
假設(shè)你有一個(gè)函數(shù)可以在一段隨機(jī)的時(shí)間后打印一個(gè)字符串:
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()
每次調(diào)用printAll時(shí),您會(huì)注意到A,B和C以不同的隨機(jī)順序打??!
這是因?yàn)檫@些函數(shù)是異步的。每個(gè)函數(shù)按順序執(zhí)行,但每個(gè)函數(shù)都獨(dú)立于它自己的setTimeout。在開(kāi)始之前,他們不會(huì)等待最后一個(gè)功能完成。
這非常煩人,所以讓我們用回調(diào)修復(fù)它。
Callbacks回調(diào)是傳遞給另一個(gè)函數(shù)的函數(shù)。第一個(gè)函數(shù)完成后,它將運(yùn)行第二個(gè)函數(shù)。
function printString(string, callback){ setTimeout( () => { console.log(string) callback() }, Math.floor(Math.random() * 100) + 1 ) }
你可以看到,修改原始函數(shù)是非常容易的,可以使用回調(diào)。
再次,讓我們嘗試按順序打印字母A,B,C:
function printAll(){ printString("A", () => { printString("B", () => { printString("C", () => {}) }) }) } printAll()
嗯,代碼現(xiàn)在很丑陋,但至少它有效!每次調(diào)用printAll時(shí),都會(huì)得到相同的結(jié)果。
回調(diào)的問(wèn)題是它創(chuàng)建了一個(gè)名為“Callback Hell”的東西。基本上,你開(kāi)始在函數(shù)內(nèi)的函數(shù)內(nèi)嵌套函數(shù),并且開(kāi)始變得非常難以閱讀代碼。
PromisePromise嘗試修復(fù)這個(gè)嵌套問(wèn)題。讓我們改變我們的功能來(lái)使用Promises
function printString(string){ return new Promise((resolve, reject) => { setTimeout( () => { console.log(string) resolve() }, Math.floor(Math.random() * 100) + 1 ) }) }
你可以看到它看起來(lái)仍然非常相似。您將整個(gè)函數(shù)包裝在Promise中,而不是調(diào)用回調(diào),而是調(diào)用resolve(如果出現(xiàn)錯(cuò)誤則拒絕)。該函數(shù)返回此Promise對(duì)象。
再次,讓我們嘗試按順序打印字母A,B,C:
function printAll(){ printString("A") .then(() => { return printString("B") }) .then(() => { return printString("C") }) } printAll()
這被稱(chēng)為承諾鏈。您可以看到代碼返回函數(shù)的結(jié)果(將是Promise),并將其發(fā)送到鏈中的下一個(gè)函數(shù)。
代碼不再嵌套,但看起來(lái)仍然很混亂!
通過(guò)使用箭頭函數(shù)的功能,我們可以刪除“包裝器”功能。代碼變得更清晰,但仍然有很多不必要的括號(hào):
function printAll(){ printString("A") .then(() => printString("B")) .then(() => printString("C")) } printAll()Await
Await基本上是Promises的語(yǔ)法糖。它使您的異步代碼看起來(lái)更像是同步/過(guò)程代碼,人類(lèi)更容易理解。
該P(yáng)RINTSTRING功能不自許的版本在所有改變。
再次,讓我們嘗試按順序打印字母A,B,C:
async function printAll(){ await printString("A") await printString("B") await printString("C") } printAll()
是啊...。好多了!
您可能會(huì)注意到我們對(duì)包裝函數(shù)printAll使用“async”關(guān)鍵字。這讓我們的JavaScript知道我們正在使用async / await語(yǔ)法,如果你想使用Await,這是必要的。這意味著你不能在全球范圍內(nèi)使用Await; 它總是需要一個(gè)包裝函數(shù)。大多數(shù)JavaScript代碼都在函數(shù)內(nèi)部運(yùn)行,因此這不是什么大問(wèn)題。
等等,這里還有更多哦該P(yáng)RINTSTRING函數(shù)不返回任何東西,是獨(dú)立的,所有我們關(guān)心的是順序。但是,如果您想獲取第一個(gè)函數(shù)的輸出,在第二個(gè)函數(shù)中執(zhí)行某些操作,然后將其傳遞給第三個(gè)函數(shù),該怎么辦?
我們不是每次都打印字符串,而是創(chuàng)建一個(gè)連接字符串并傳遞它的函數(shù)。
Callbacks這里是回調(diào)樣式:
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風(fēng)格:
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()
使用箭頭函數(shù)意味著我們可以使代碼更好一些:
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()
這肯定更具可讀性,特別是如果你向鏈添加更多,但仍然是一堆括號(hào)。
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~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/101638.html
摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...
摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...
摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無(wú)法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱(chēng)是_異步_。那是什么意思?它如何影響發(fā)展?近年來(lái)這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語(yǔ)言都處理每...
摘要:讓我們使用它從數(shù)組中返回一個(gè)值數(shù)組在中,我們可以這樣做,這是一種更簡(jiǎn)單的方法最重要的部分是創(chuàng)建數(shù)組,該數(shù)組立即調(diào)用所有的我們?cè)谥骱瘮?shù)中等待這些。所以在我們真正等待完成之前,主函數(shù)就退出了。 原文: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...
閱讀 2078·2021-11-24 09:39
閱讀 3511·2021-09-22 14:58
閱讀 1343·2019-08-30 15:54
閱讀 3467·2019-08-29 11:33
閱讀 1930·2019-08-26 13:54
閱讀 1806·2019-08-26 13:35
閱讀 2628·2019-08-23 18:14
閱讀 914·2019-08-23 17:04