摘要:由于我們沒有,或者的結果,所以我們無法對它做出任何反應。因為我們等待了的返回值,所以它的會被返回并且被拋出,的代碼塊就會執行。但無論如何,如果沒有報錯而是順利執行,我們依舊無法對它的返回值做任何事情。
原文地址:await vs return vs return await
作者:Jake Archibald
當編寫異步函數的時候,await,return,return await三者之間有一些區別,從中選取正確的方式是很重要的。
我們從下面這個異步函數開始:
async function waitAndMaybeReject(){ // 等待1秒鐘 await new Promise(resolve => setTimeout(resolve, 1000)); // 拋一枚硬幣 const isHeads = Boolean(Math.round(Math.random())); if(isHeads) return "yay"; throw Error("Boo!"); }
上面的函數會等待1秒鐘后返回一個promise,然后有50%的機會成功返回yay或者拋出一個error。讓我們用幾種稍微不同的方式使用它。
直接調用async function foo() { try{ waitAndMaybeReject(); }catch(e){ return "caught"; } }
在此處,如果調用了foo,返回的promise的狀態始終都是resolved,值也永遠是undefined,而且沒有等待。
由于我們沒有await,或者return waitAndMaybeReject()的結果,所以我們無法對它做出任何反應。像這樣的代碼通常是錯誤的。
async function foo(){ try{ await waitAndMaybeReject(); }catch(e){ return "caught"; } }
在此處,如果調用了foo,返回的promise將始終等待1秒鐘,然后結果要么狀態為resolved,值為undefined,要么狀態為resolved,值為"caught"。
因為我們等待了waitAndMaybeReject()的返回值,所以它的rejection會被返回并且被拋出(throw),catch的代碼塊就會執行。但無論如何,如果waitAndMaybeReject()沒有報錯而是順利執行,我們依舊無法對它的返回值做任何事情。
async function foo() { try { return waitAndMaybeReject(); } catch (e) { return "caught"; } }
在此處,如果調用了foo,返回的promise將始終等待1秒鐘,然后結果要么是狀態為resolved,值為"yaa",要么是狀態是reject,拋出錯誤Error("Boo!")。
通過return waitAndMaybeReject()這行代碼,我們直接傳遞了它的返回結果,所以我們的catch代碼塊永遠不會執行。
如果你想在try代碼塊中得到帶有正確返回值的resolved狀態,在catch中捕獲異常,那么正確的選擇就是return await。
async function foo() { try { return await waitAndMaybeReject(); } catch (e) { return "caught"; } }
在此處,如果調用foo,返回的promise將始終等待1秒鐘,然后結果要么是狀態為resolved,值為"yay",要么是狀態為resolved,值為"caught"
因為我們等待了waitAndMaybeReject()的結果,所以它的異常rejecttion會被返回并且被拋出(throw),catch的代碼塊就會執行。如果waitAndMaybeReject()順利執行沒有報錯,就返它的結果。
如果對上面的內容還是覺著困惑,那么將代碼拆分成兩個步驟來看可能會比較好理解:
async function foo() { try { // 等待 waitAndMaybeReject() 的結果來解決, // 并且將 fullfill 的值賦給 fullfilledValue: const fulfilledValue = await waitAndMaybeReject(); // 如果 waitAndMaybeReject() reject了, // 我們的代碼就會拋出異常,并且進入 catch 代碼塊的邏輯。 // 否則,這里的代碼就會繼續運行下面的語句: return fulfilledValue; } catch (e) { return "caught"; } }
Note: 在try/catch之外的代碼塊中執行return await是多余的(如前所述,直接return即可),甚至Eslint還專門有規則來檢測這種場景,但是在try/catch代碼塊之內,Eslint就允許這種操作。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99336.html
摘要:異步流程管理說白了就是為了解決回調地獄的問題。對象代表一個異步操作,有三種狀態進行中已成功和已失敗。如果改變已經發生了,你再對對象添加回調函數,也會立即得到這個結果。執行函數后返回的是一個遍歷器對象,可以依次遍歷函數內部的每一個狀態。 javascript -- 深度解析異步解決方案 高級語言層出不窮, 然而唯 js 鶴立雞群, 這要說道js的設計理念, js天生為異步而生, 正如布道...
摘要:本文討論地址閱讀時間大概分鐘和有很多容易被忽視的不同之處。首先定義一個異步函數等待秒函數等待秒鐘,然后有一半的概率返回,一半的概率拋出異常。這個是最符合我們預期的寫法。 dev-reading/fe 是一個閱讀、導讀、速讀的 repo,不要依賴于 dev-reading/fe 學習知識。本 repo 只是一個快速了解文章內容的工具,并不提供全文解讀和翻譯。你可以通過本平臺快速了解文章里...
摘要:對于,除非使用箭頭函數,它的回調函數的將會變化。使用測試下面的代碼,結果如下打印打印要點使用的規則要求所有回調函數必須使用箭頭函數。 譯者按: JS 騷操作。 原文:For vs forEach() vs for/in vs for/of in JavaScript 譯者: Fundebug 本文采用意譯,版權歸原作者所有 我們有多種方法來遍歷 JavaScript 的數組或者...
摘要:的科學定義是或者,它的標志性原語是。能解決一類對語言的實現來說特別無力的狀態機模型流程即狀態。容易實現是需要和的一個重要原因。 前面寫了一篇,寫的很粗,這篇講講一些細節。實際上Fiber/Coroutine vs Async/Await之爭不是一個簡單的continuation如何實現的問題,而是兩個完全不同的problem和solution domain。 Event Model 我...
摘要:如果是你是高級或者初級開發人員,了解它的基本概念非常重要。由于是基本類型,因此的值等于的值,并且可以認為此時與完全不同。展開運算符可用于提取數組的各個元素。函數本身返回從數組中刪除的項。如果未指定結束位置,則返回數組的其余部分。 譯者:前端小智 原文:hackernoon.com/12-javascri… JavaScript 是一種復雜的語言。如果是你是高級或者初級 JavaScript...
閱讀 2830·2021-09-10 10:50
閱讀 2192·2019-08-29 16:06
閱讀 3196·2019-08-29 11:02
閱讀 1093·2019-08-26 14:04
閱讀 2803·2019-08-26 13:24
閱讀 2301·2019-08-26 12:16
閱讀 550·2019-08-26 10:29
閱讀 3094·2019-08-23 18:33