await vs return vs return await關(guān)鍵區(qū)別解析

JavaScript 異步編程
異步編程是現(xiàn)代 JavaScript 開(kāi)發(fā)中一個(gè)重要方面,它使我們能夠處理耗時(shí)的操作,而不會(huì)阻塞其他任務(wù)的執(zhí)行。使用異步函數(shù)時(shí),我們會(huì)遇到三個(gè)重要的關(guān)鍵字:await 、return、return await。在本文中,我們將探討這些關(guān)鍵字之間的差異,并討論何時(shí)使用每個(gè)關(guān)鍵字。
在深入探討細(xì)節(jié)之前,讓我們先闡明一下異步函數(shù)的用途。異步函數(shù)是一種特殊類型的函數(shù),可以使用 await 關(guān)鍵字。它允許我們以更加同步和可讀的方式編寫(xiě)異步代碼,從而更容易處理 Promise 和執(zhí)行非阻塞操作。當(dāng)調(diào)用異步函數(shù)時(shí),它會(huì)返回一個(gè) Promise,該 Promise 解析為函數(shù)的最終結(jié)果。
現(xiàn)在,讓我們探討一下 await 、return、 和 return await 在異步函數(shù)上下文中的差異。
讓我們從這個(gè)異步函數(shù)開(kāi)始:
async function waitAndMaybeReject() {
// 等待 1s
await new Promise(r => setTimeout(r, 1000));
// 擲硬幣
const isHeads = Boolean(Math.round(Math.random()));
if(isHeads) return 'yay';
throw Error('Boo!');
}它會(huì)返回一個(gè)等待一秒的 Promise,然后 50% 的幾率以 "yay" 表示,或以錯(cuò)誤拒絕,讓我們以幾種微妙的方式來(lái)使用它。
只是調(diào)用
讓我們先來(lái)看一下,當(dāng)我們簡(jiǎn)單地調(diào)用另一個(gè)異步函數(shù)而不正確處理返回的 Promise 時(shí),異步函數(shù)的行為。請(qǐng)看下面的示例:
async function foo() {
try {
waitAndMaybeReject();
} catch(e) {
return 'caught';
}
}在這里,如果直接調(diào)用 foo,異步函數(shù) foo 返回的 Promise 將始終以 undefined 表示,而無(wú)需等待函數(shù) waitAndMaybeReject。
因?yàn)槲覀儧](méi)有 await 或者 return 異步函數(shù) waitAndMaybeReject() 的結(jié)果,因此我們對(duì)它沒(méi)有作出任何反應(yīng),像這樣的代碼通常都是錯(cuò)誤的。
Await
關(guān)鍵字 await 在異步代碼中起著至關(guān)重要的作用,它允許我們暫停異步函數(shù)的執(zhí)行,直到承諾得到解決或拒絕,讓我們看看它與僅調(diào)用 async 函數(shù)有何不同。
await 的本質(zhì):
- 異步代碼同步:
await通過(guò)阻塞執(zhí)行,直到等待的 Promise 被解析或拒絕,簡(jiǎn)化了異步代碼的使用。 - 增強(qiáng)的可讀性:它消除了深度嵌套回調(diào)或
then()長(zhǎng)鏈的需要,從而極大地提高了代碼的可讀性。
async function foo() {
try {
await waitAndMaybeReject();
} catch(e) {
return 'caught';
}
}在這里,如果調(diào)用 foo,返回的 Promise 總是會(huì)等待一秒,然后以 undefined 或以 "caught" 表示 fulfill。
因?yàn)槲覀?nbsp;await waitAndMaybeReject() 的結(jié)果,所以它 rejection 時(shí),將變成錯(cuò)誤拋出,我們的 catch 代碼塊也將執(zhí)行。但是,如果 waitAndMaybeReject() 執(zhí)行完畢,我們不會(huì)對(duì)值做任何處理。
Return
async function foo() {
try {
return waitAndMaybeReject();
} catch(e) {
return 'caught';
}
}在這里,如果你調(diào)用 foo,返回的 Promise 將始終等待一秒,然后要么以 "yay" 表示 fulfill,要么以 Error('Boo!') 表示 reject。
由于通過(guò) return waitAndMaybeReject,我們延遲了其結(jié)果,因此我們的 catch 代碼塊永遠(yuǎn)不會(huì)運(yùn)行。
Return await
在 try/catch 塊中,你需要的是 return await。
retrun await 的本質(zhì):
- 一致的值:
return await可確保函數(shù)始終一致的返回 Promise 的解析值,即使在沒(méi)有嚴(yán)格必要的情況下也是如此,從而確保返回?cái)?shù)據(jù)類型的一致性。 - 控制流清晰:在有條件邏輯的情況下,
return await可以提供更清晰的控制流,從而更容易跟蹤代碼的執(zhí)行路徑。
async function foo() {
try {
return await waitAndMaybeReject();
} catch(e) {
return 'caught';
}
}在這里,如果調(diào)用 foo,將始終等待一秒后返回 Promise,然后以 "yay" 或者以 "caught" 表示 fulfill。
因?yàn)槲覀兊却?nbsp;waitAndMaybeReject() 的結(jié)果,所以它的 rejection 將變成拋出的 throw,我們的 catch 代碼塊將執(zhí)行。如果 waitAndMaybeReject() 執(zhí)行完畢,我們將返回其結(jié)果。
如果上述內(nèi)容看起來(lái)令人困惑,那么將其視為兩個(gè)獨(dú)立的步驟可能會(huì)更容易理解:
async function foo() {
try {
// 等待 waitAndMaybeReject() 的結(jié)果結(jié)算,
// 并將已完成的值分配給 fulfilledValue:
const fulfillValue = await waitAndMaybeReject();
// 如果 waitAndMaybeReject() 的結(jié)果被拒絕,我們的代碼就會(huì)拋出,然后跳到 catch 塊。
// 否則,此塊將繼續(xù)運(yùn)行:
return fulfillValue;
} catch(e) {
return 'caught';
}
}注意:在 try/catch 塊之外,return await 是多余的,ESLint 甚至有一條規(guī)則來(lái)檢測(cè)它,但它允許在 try/catch 中使用。
參考:
- https://jakearchibald.com/2017/await-vs-return-vs-return-await/
- https://levelup.gitconnected.com/understanding-the-crucial-di...
以上就是await vs return vs return await關(guān)鍵區(qū)別解析的詳細(xì)內(nèi)容,更多關(guān)于await vs return vs return await的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
輸入框跟隨文字內(nèi)容適配寬實(shí)現(xiàn)示例
這篇文章主要為大家介紹了輸入框跟隨文字內(nèi)容適配寬實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
umi插件開(kāi)發(fā)仿dumi項(xiàng)目自動(dòng)生成導(dǎo)航欄實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了umi插件開(kāi)發(fā)仿dumi項(xiàng)目自動(dòng)生成導(dǎo)航欄實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
微信小程序 解析網(wǎng)頁(yè)內(nèi)容詳解及實(shí)例
這篇文章主要介紹了微信小程序 解析網(wǎng)頁(yè)內(nèi)容詳解及實(shí)例的相關(guān)資料,這里使用爬蟲(chóng)對(duì)復(fù)雜的網(wǎng)頁(yè)進(jìn)行抓取,遇到些問(wèn)題,這里整理下并解決,需要的朋友可以參考下2017-02-02
electron創(chuàng)建新窗口模態(tài)框并實(shí)現(xiàn)主進(jìn)程傳值給子進(jìn)程
這篇文章主要為大家介紹了electron創(chuàng)建新窗口模態(tài)框并實(shí)現(xiàn)主進(jìn)程傳值給子進(jìn)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
學(xué)習(xí)筆記編寫(xiě)vue的第一個(gè)程序
這篇文章主要介紹了學(xué)習(xí)筆記vue的第一個(gè)程序,其中非常詳細(xì)的為大家講解了vue程序的創(chuàng)建步驟,有需要的朋友可以學(xué)習(xí)下,希望可以有所幫助2021-08-08
Javascript閉包使用場(chǎng)景原理詳細(xì)
這篇文章主要介紹了Javascript閉包的使用場(chǎng)景, 由于在Javascript語(yǔ)言中,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量,閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)。所以,在本質(zhì)上,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來(lái)的一座橋梁,下面一起進(jìn)入文化在哪個(gè)了解文章內(nèi)容2021-11-11

