await vs return vs return await關(guān)鍵區(qū)別解析
JavaScript 異步編程
異步編程是現(xiàn)代 JavaScript 開發(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)鍵字。它允許我們以更加同步和可讀的方式編寫異步代碼,從而更容易處理 Promise 和執(zhí)行非阻塞操作。當(dāng)調(diào)用異步函數(shù)時(shí),它會(huì)返回一個(gè) Promise,該 Promise 解析為函數(shù)的最終結(jié)果。
現(xiàn)在,讓我們探討一下 await
、return
、 和 return await
在異步函數(shù)上下文中的差異。
讓我們從這個(gè)異步函數(shù)開始:
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ò)誤拒絕,讓我們以幾種微妙的方式來使用它。
只是調(diào)用
讓我們先來看一下,當(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
表示,而無需等待函數(shù) waitAndMaybeReject
。
因?yàn)槲覀儧]有 await
或者 return
異步函數(shù) waitAndMaybeReject()
的結(jié)果,因此我們對(duì)它沒有作出任何反應(yīng),像這樣的代碼通常都是錯(cuò)誤的。
Await
關(guān)鍵字 await
在異步代碼中起著至關(guān)重要的作用,它允許我們暫停異步函數(shù)的執(zhí)行,直到承諾得到解決或拒絕,讓我們看看它與僅調(diào)用 async 函數(shù)有何不同。
await
的本質(zhì):
- 異步代碼同步:
await
通過阻塞執(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。
由于通過 return waitAndMaybeReject
,我們延遲了其結(jié)果,因此我們的 catch 代碼塊永遠(yuǎn)不會(huì)運(yùn)行。
Return await
在 try/catch
塊中,你需要的是 return await
。
retrun await
的本質(zhì):
- 一致的值:
return await
可確保函數(shù)始終一致的返回 Promise 的解析值,即使在沒有嚴(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)容看起來令人困惑,那么將其視為兩個(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ī)則來檢測(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)文章
JavaScript 運(yùn)行機(jī)制詳解再淺談Event Loop
這篇文章主要介紹了JavaScript 運(yùn)行機(jī)制詳解及淺談了Event Loop,感興趣的小伙伴可以和小編一起閱讀下面文章的具體內(nèi)容2021-09-09微信小程序 動(dòng)態(tài)傳參實(shí)例詳解
這篇文章主要介紹了微信小程序 動(dòng)態(tài)傳參實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-04-04JavaScript?定時(shí)器關(guān)鍵點(diǎn)及使用場(chǎng)景解析
這篇文章主要為大家介紹了JavaScript?定時(shí)器關(guān)鍵點(diǎn)及使用場(chǎng)景解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01requestAnimationFrame定時(shí)動(dòng)畫屏幕刷新率節(jié)流示例淺析
這篇文章主要為大家介紹了requestAnimationFrame定時(shí)動(dòng)畫屏幕刷新率節(jié)流示例淺析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02