JavaScript 回圈中呼叫異步函式的三種方法,及為什么 forEach 無法作業的分析
業務分析 初版的問題 解決方案 傳統的 for 回圈 不使用 for 回圈的解決方案 分析 forEach 為什么不作業 并行解決方案 串行解決方案
總結
本文主要分析在回圈體中怎么呼叫異步函式,并且滿足回圈呼叫異步函式,并在異步函式值回傳之后,再處理后續業務的同步需求,
這篇文章是受到和 六卿 在群里討論問題時啟發而寫的,主要討論的問題就只在回圈體內進行異步呼叫,他也寫了自己的總結: node 中回圈異步的問題[‘解決方案‘]_源于 map 回圈和 for 回圈對異步事件配合 async、await 的支持,
業務分析
根據我的理解,當時討論的問題是基于這樣一個需求:
首先需要呼叫一個 API 去獲得資料
獲取的資料是一個陣列型別,這里就代稱為 arr
會對 arr 進行遍歷,在遍歷的程序中繼續呼叫其他的 API 去獲得資料,并且對資料進行一些操作
整體的業務邏輯和需求,模擬大概是這個樣子的:
const map = new Map ( [
[ 1 , 'one' ] ,
[ 2 , 'two' ] ,
[ 3 , 'three' ] ,
[ 4 , 'four' ] ,
[ 5 , 'five' ] ,
] ) ;
// 用 setTimeout 模擬異步的 api 呼叫
// timeout 會獲得一個陣列型別的資料,隨后會有另外的 api 根據陣列內的資料,再一次去進行異步呼叫,獲取其他資料
const timeout = ( ) =>
new Promise ( ( resolve ) => setTimeout ( ( ) => resolve ( [ 1 , 2 , 3 , 4 , 5 ] ) ) , 1000 ) ;
// 回圈體內呼叫的資料
const getEl = ( key ) =>
new Promise ( ( resolve ) => setTimeout ( ( ) => resolve ( map. get ( key) ) , 1000 ) ) ;
const getData = ( ) => {
const data = timeout ( ) ;
let str = [ ] ;
// 這里沒有處理異步操作,所以會有語法錯誤
data. forEach ( ( el ) => {
const elVal = getEl ( el) ;
str. push ( elVal) ;
} ) ;
// 最后輸出結果應該是 ['one', 'two', ...] 這樣一個包含 異步呼叫后回傳值 的陣列
console. log ( str) ;
} ;
getData ( ) ;
當然,上面只是一個最基本的邏輯實作,并沒有實作異步操作,現在直接運行的話就會報錯,不過基本的邏輯是在這里的:
API 那里獲取到值 data 遍歷 data,在遍歷中繼續呼叫 API 取值并進行操作,
初版的問題
最初的方案其實就是比較平鋪直敘,用 async/await 配合的方式去獲取資料:
// 其他函式沒有改動,只修改了 getData 這一部分
const getData = async ( ) => {
// 使用 await 語法糖
const data = await timeout ( ) ;
let str = [ ] ;
// 加上 async 和 await 去等待異步呼叫
data. forEach ( async ( el ) => {
const elVal = await getEl ( el) ;
str. push ( elVal) ;
// 可以正常輸出
console. log ( elVal) ;
} ) ;
// 回傳值卻是一個空陣列
console. log ( str) ;
} ;
getData ( ) ;
輸出結果卻不盡如人意,在命令列中輸出的順序是這樣的:
[ ]
one
two
three
four
five
可以看到,異步的資料獲取是在輸出陣列之后發生的,這也代表 forEach 內的異步呼叫的順序,不如預期所想,
解決方案
改為 for回圈體 是 六卿 在自己的總結內提出的解決方案;這里再提出了兩個不使用 for回圈體 的解決方案,
傳統的 for 回圈
一個解決方案就是將 forEach/map 替換成傳統的 for (let i = 0; i < arr.lengt; i++) 這樣的傳統寫法,如:
const getData2 = async ( ) => {
const data = await timeout ( ) ;
let str = [ ] ;
for ( let i = 0 ; i < data. length; i++ ) {
const element = await getEl ( data[ i] ) ;
console. log ( element) ;
str. push ( element) ;
}
console. log ( str) ;
} ;
getData2 ( ) ;
最終的輸出結果為:
one
two
three
four
five
[ 'one' , 'two' , 'three' , 'four' , 'five' ]
陣列的輸出結果在 API 呼叫結果之后,也就意味著資料可以正常地被渲染或是處理,
不使用 for 回圈的解決方案
所以異步的代碼只能使用傳統的 for 回圈嗎?
也不盡然,只是解決方法無法基于 forEach 去實作而已,
分析 forEach 為什么不作業
在輸出的時候我發現了一些微妙的例外,例如說使用 for 回圈時,每一行的輸出都是有一定間隔事件的——畢竟 await 應該會“鎖”住運行,一直到資料接收之后才會進行下一步的呼叫,但是使用 forEach 函式時,它等待了大約幾秒鐘的時間,隨后一下子將所有的結果一起輸出,
直接用文字描述可能沒有這么直觀,那么就打幾個時間戳,一個在剛剛進入函式的時候列印出當前時間,一個在回圈體內輸出值的時候列印出當前時間,更加直觀的對比一下:
forEach for
也就是說,forEach 的回圈呼叫并沒有 await 里面的異步操作,所以,當 forEach 中的同步代碼執行完畢之后,異步代碼才開始執行,這也是為什么 forEach 的代碼先輸出了一個空的陣列之后,才在控制臺上列印異步呼叫中獲取的值,
異步呼叫的復習資料在這里:[萬字詳解]JavaScript 中的異步模式及 Promise 使用
那么,函式最上方已經宣告了 async 關鍵字,forEach 中也使用了 await 去等數,而且,明明 await timeout() 作業了,為什么就只有 forEach 沒有作業?
那是因為,forEach 整個函式沒有使用 await 進行等待,整個 forEach 是同步執行的,forEach 的實作是基于內部的回呼函式執行,因此,當進入回圈之后,函式內部會去呼叫傳進來的回呼函式,當回呼函式是異步時,回呼函式就會被放入時間回圈機制中,forEach 內部會繼續去執行同步代碼,也就是繼續回圈,
很可惜的是,基于歷史原因——forEach 函式是 ES5 時代的函式,Promise 等異步操作的支持是 ES6 以后才有的支持——直接使用 forEach 是沒有辦法實作在回圈體內呼叫異步函式的方法,
但是,都 2021 年了,這也不代表沒有解決方案,
并行解決方案
如果資料彼此之間沒有依賴關系,其實個人更建議使用這種方式,相對而言效率會更高一些,
實作的方式是 Promise.all 結合 await 和 map 去實作:
Promise.all 可以接收由 Promise 組成的陣列,并且回傳一個 Promise,
map 的特性與 forEach 相似,區別在于前者會回傳一個陣列,后者會回傳一個 undefined,
Promise.all 的引數正好又是一個由 Promise 組成的陣列;并且,Promise.all 的回傳值就是一個 Promise
await 是 ES7 推出的語法糖,可以用來等待一個 Promise 的執行完成,
所以結合 Promise.all,await 和 map 就可以近似同步地發送多個異步請求,之所以說是 近似 ,還是因為畢竟是一個迭代,總歸需要按序陣列中第一個元素開始執行,只不過大多數情況下,陣列的迭代與異步操作比起來消耗時間可以小到近乎不計,
實作如下:
const getData = async ( ) => {
const data = await timeout ( ) ;
const curr = new Date ( ) ;
console. log ( curr) ;
let str = [ ] ;
// 使用 Promise.all 去等待內部所有的 Promise 執行完畢
await Promise. all ( data. map ( ( el ) => getEl ( el) ) ) . then ( ( val ) => {
str = val;
console. log ( new Date ( ) - curr) ;
return val;
} ) ;
console. log ( str) ;
} ;
getData ( ) ;
效果截圖:
可以看出,與最初使用傳統的 for 回圈相比,使用 Promise.all 能夠有效的提升性能,當有多個較為耗時的異步任務,并且彼此之間沒有依賴關系的時候,為了能夠提升用戶體驗,最好還是使用 Promise.all 去呼叫,
這是因為 await 等待的是所有的 Promise 執行完畢的結果,即鎖住的是 Promise.all,而內部的 map 依舊是同步執行的,所以對于回圈體內的異步函式來說,它不需要等待上一個迭代完成,再去執行下一個迭代——await 這個語法糖會等待 Promise 執行完畢再去執行下一個 Promise,
其執行流程大概如下:
<style>#mermaid-svg-5R7DtKuepLB4Omuv .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-5R7DtKuepLB4Omuv .label text{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .node rect,#mermaid-svg-5R7DtKuepLB4Omuv .node circle,#mermaid-svg-5R7DtKuepLB4Omuv .node ellipse,#mermaid-svg-5R7DtKuepLB4Omuv .node polygon,#mermaid-svg-5R7DtKuepLB4Omuv .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-5R7DtKuepLB4Omuv .node .label{text-align:center;fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .node.clickable{cursor:pointer}#mermaid-svg-5R7DtKuepLB4Omuv .arrowheadPath{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-5R7DtKuepLB4Omuv .flowchart-link{stroke:#333;fill:none}#mermaid-svg-5R7DtKuepLB4Omuv .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-5R7DtKuepLB4Omuv .edgeLabel rect{opacity:0.9}#mermaid-svg-5R7DtKuepLB4Omuv .edgeLabel span{color:#333}#mermaid-svg-5R7DtKuepLB4Omuv .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-5R7DtKuepLB4Omuv .cluster text{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-5R7DtKuepLB4Omuv .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-5R7DtKuepLB4Omuv text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-5R7DtKuepLB4Omuv .actor-line{stroke:grey}#mermaid-svg-5R7DtKuepLB4Omuv .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-5R7DtKuepLB4Omuv .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-5R7DtKuepLB4Omuv #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-5R7DtKuepLB4Omuv .sequenceNumber{fill:#fff}#mermaid-svg-5R7DtKuepLB4Omuv #sequencenumber{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv #crosshead path{fill:#333;stroke:#333}#mermaid-svg-5R7DtKuepLB4Omuv .messageText{fill:#333;stroke:#333}#mermaid-svg-5R7DtKuepLB4Omuv .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-5R7DtKuepLB4Omuv .labelText,#mermaid-svg-5R7DtKuepLB4Omuv .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-5R7DtKuepLB4Omuv .loopText,#mermaid-svg-5R7DtKuepLB4Omuv .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-5R7DtKuepLB4Omuv .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-5R7DtKuepLB4Omuv .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-5R7DtKuepLB4Omuv .noteText,#mermaid-svg-5R7DtKuepLB4Omuv .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-5R7DtKuepLB4Omuv .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-5R7DtKuepLB4Omuv .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-5R7DtKuepLB4Omuv .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-5R7DtKuepLB4Omuv .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .section{stroke:none;opacity:0.2}#mermaid-svg-5R7DtKuepLB4Omuv .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-5R7DtKuepLB4Omuv .section2{fill:#fff400}#mermaid-svg-5R7DtKuepLB4Omuv .section1,#mermaid-svg-5R7DtKuepLB4Omuv .section3{fill:#fff;opacity:0.2}#mermaid-svg-5R7DtKuepLB4Omuv .sectionTitle0{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .sectionTitle1{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .sectionTitle2{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .sectionTitle3{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-5R7DtKuepLB4Omuv .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .grid path{stroke-width:0}#mermaid-svg-5R7DtKuepLB4Omuv .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-5R7DtKuepLB4Omuv .task{stroke-width:2}#mermaid-svg-5R7DtKuepLB4Omuv .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .taskText:not([font-size]){font-size:11px}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-5R7DtKuepLB4Omuv .task.clickable{cursor:pointer}#mermaid-svg-5R7DtKuepLB4Omuv .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-5R7DtKuepLB4Omuv .taskText0,#mermaid-svg-5R7DtKuepLB4Omuv .taskText1,#mermaid-svg-5R7DtKuepLB4Omuv .taskText2,#mermaid-svg-5R7DtKuepLB4Omuv .taskText3{fill:#fff}#mermaid-svg-5R7DtKuepLB4Omuv .task0,#mermaid-svg-5R7DtKuepLB4Omuv .task1,#mermaid-svg-5R7DtKuepLB4Omuv .task2,#mermaid-svg-5R7DtKuepLB4Omuv .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutside0,#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutside2{fill:#000}#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutside1,#mermaid-svg-5R7DtKuepLB4Omuv .taskTextOutside3{fill:#000}#mermaid-svg-5R7DtKuepLB4Omuv .active0,#mermaid-svg-5R7DtKuepLB4Omuv .active1,#mermaid-svg-5R7DtKuepLB4Omuv .active2,#mermaid-svg-5R7DtKuepLB4Omuv .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-5R7DtKuepLB4Omuv .activeText0,#mermaid-svg-5R7DtKuepLB4Omuv .activeText1,#mermaid-svg-5R7DtKuepLB4Omuv .activeText2,#mermaid-svg-5R7DtKuepLB4Omuv .activeText3{fill:#000 !important}#mermaid-svg-5R7DtKuepLB4Omuv .done0,#mermaid-svg-5R7DtKuepLB4Omuv .done1,#mermaid-svg-5R7DtKuepLB4Omuv .done2,#mermaid-svg-5R7DtKuepLB4Omuv .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-5R7DtKuepLB4Omuv .doneText0,#mermaid-svg-5R7DtKuepLB4Omuv .doneText1,#mermaid-svg-5R7DtKuepLB4Omuv .doneText2,#mermaid-svg-5R7DtKuepLB4Omuv .doneText3{fill:#000 !important}#mermaid-svg-5R7DtKuepLB4Omuv .crit0,#mermaid-svg-5R7DtKuepLB4Omuv .crit1,#mermaid-svg-5R7DtKuepLB4Omuv .crit2,#mermaid-svg-5R7DtKuepLB4Omuv .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-5R7DtKuepLB4Omuv .activeCrit0,#mermaid-svg-5R7DtKuepLB4Omuv .activeCrit1,#mermaid-svg-5R7DtKuepLB4Omuv .activeCrit2,#mermaid-svg-5R7DtKuepLB4Omuv .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-5R7DtKuepLB4Omuv .doneCrit0,#mermaid-svg-5R7DtKuepLB4Omuv .doneCrit1,#mermaid-svg-5R7DtKuepLB4Omuv .doneCrit2,#mermaid-svg-5R7DtKuepLB4Omuv .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-5R7DtKuepLB4Omuv .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-5R7DtKuepLB4Omuv .milestoneText{font-style:italic}#mermaid-svg-5R7DtKuepLB4Omuv .doneCritText0,#mermaid-svg-5R7DtKuepLB4Omuv .doneCritText1,#mermaid-svg-5R7DtKuepLB4Omuv .doneCritText2,#mermaid-svg-5R7DtKuepLB4Omuv .doneCritText3{fill:#000 !important}#mermaid-svg-5R7DtKuepLB4Omuv .activeCritText0,#mermaid-svg-5R7DtKuepLB4Omuv .activeCritText1,#mermaid-svg-5R7DtKuepLB4Omuv .activeCritText2,#mermaid-svg-5R7DtKuepLB4Omuv .activeCritText3{fill:#000 !important}#mermaid-svg-5R7DtKuepLB4Omuv .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-5R7DtKuepLB4Omuv g.classGroup text .title{font-weight:bolder}#mermaid-svg-5R7DtKuepLB4Omuv g.clickable{cursor:pointer}#mermaid-svg-5R7DtKuepLB4Omuv g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-5R7DtKuepLB4Omuv g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-5R7DtKuepLB4Omuv .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-5R7DtKuepLB4Omuv .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-5R7DtKuepLB4Omuv .dashed-line{stroke-dasharray:3}#mermaid-svg-5R7DtKuepLB4Omuv #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv .commit-id,#mermaid-svg-5R7DtKuepLB4Omuv .commit-msg,#mermaid-svg-5R7DtKuepLB4Omuv .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-5R7DtKuepLB4Omuv g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-5R7DtKuepLB4Omuv g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-5R7DtKuepLB4Omuv g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-5R7DtKuepLB4Omuv .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-5R7DtKuepLB4Omuv .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-5R7DtKuepLB4Omuv .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-5R7DtKuepLB4Omuv .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-5R7DtKuepLB4Omuv .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-5R7DtKuepLB4Omuv .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-5R7DtKuepLB4Omuv .edgeLabel text{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-5R7DtKuepLB4Omuv .node circle.state-start{fill:black;stroke:black}#mermaid-svg-5R7DtKuepLB4Omuv .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-5R7DtKuepLB4Omuv #statediagram-barbEnd{fill:#9370db}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-state .divider{stroke:#9370db}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-5R7DtKuepLB4Omuv .note-edge{stroke-dasharray:5}#mermaid-svg-5R7DtKuepLB4Omuv .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-5R7DtKuepLB4Omuv .error-icon{fill:#522}#mermaid-svg-5R7DtKuepLB4Omuv .error-text{fill:#522;stroke:#522}#mermaid-svg-5R7DtKuepLB4Omuv .edge-thickness-normal{stroke-width:2px}#mermaid-svg-5R7DtKuepLB4Omuv .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-5R7DtKuepLB4Omuv .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-5R7DtKuepLB4Omuv .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-5R7DtKuepLB4Omuv .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-5R7DtKuepLB4Omuv .marker{fill:#333}#mermaid-svg-5R7DtKuepLB4Omuv .marker.cross{stroke:#333}
:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style>
<style>#mermaid-svg-5R7DtKuepLB4Omuv {
color: rgba(0, 0, 0, 0.75);
font: ;
}</style>
input
Promise All
iteration 1
iteration 2
iteration 3
...
iteration N
output
串行解決方案
for await...of 是基于對 iterable(可迭代) 的實作,這種實作比較適合用于有依賴關系的內容,如較大檔案的加載,可以通過在閱讀到某一個點的時候觸發下一段檔案的加載,以達到提升用戶體驗感的效果,
使用案例如下:
const getData3 = async ( ) => {
const data = await timeout ( ) ;
const curr = new Date ( ) ;
console. log ( curr) ;
let str = [ ] ;
for await ( el of data) {
const element = await getEl ( el) ;
console. log ( element, new Date ( ) - curr) ;
str. push ( element) ;
}
console. log ( str) ;
} ;
getData3 ( ) ;
效果如下:
因為使用了 await 去等待上一個異步呼叫結果回傳之后,再去執行下一個異步呼叫,因此消耗的時間也更多,
其執行流程大概如下:
<style>#mermaid-svg-JIZpbKLfRTZV4Xfm .label{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .label text{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .node rect,#mermaid-svg-JIZpbKLfRTZV4Xfm .node circle,#mermaid-svg-JIZpbKLfRTZV4Xfm .node ellipse,#mermaid-svg-JIZpbKLfRTZV4Xfm .node polygon,#mermaid-svg-JIZpbKLfRTZV4Xfm .node path{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-JIZpbKLfRTZV4Xfm .node .label{text-align:center;fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .node.clickable{cursor:pointer}#mermaid-svg-JIZpbKLfRTZV4Xfm .arrowheadPath{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .edgePath .path{stroke:#333;stroke-width:1.5px}#mermaid-svg-JIZpbKLfRTZV4Xfm .flowchart-link{stroke:#333;fill:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .edgeLabel{background-color:#e8e8e8;text-align:center}#mermaid-svg-JIZpbKLfRTZV4Xfm .edgeLabel rect{opacity:0.9}#mermaid-svg-JIZpbKLfRTZV4Xfm .edgeLabel span{color:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .cluster rect{fill:#ffffde;stroke:#aa3;stroke-width:1px}#mermaid-svg-JIZpbKLfRTZV4Xfm .cluster text{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:12px;background:#ffffde;border:1px solid #aa3;border-radius:2px;pointer-events:none;z-index:100}#mermaid-svg-JIZpbKLfRTZV4Xfm .actor{stroke:#ccf;fill:#ECECFF}#mermaid-svg-JIZpbKLfRTZV4Xfm text.actor>tspan{fill:#000;stroke:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .actor-line{stroke:grey}#mermaid-svg-JIZpbKLfRTZV4Xfm .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .messageLine1{stroke-width:1.5;stroke-dasharray:2, 2;stroke:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm #arrowhead path{fill:#333;stroke:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .sequenceNumber{fill:#fff}#mermaid-svg-JIZpbKLfRTZV4Xfm #sequencenumber{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm #crosshead path{fill:#333;stroke:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .messageText{fill:#333;stroke:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .labelBox{stroke:#ccf;fill:#ECECFF}#mermaid-svg-JIZpbKLfRTZV4Xfm .labelText,#mermaid-svg-JIZpbKLfRTZV4Xfm .labelText>tspan{fill:#000;stroke:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .loopText,#mermaid-svg-JIZpbKLfRTZV4Xfm .loopText>tspan{fill:#000;stroke:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .loopLine{stroke-width:2px;stroke-dasharray:2, 2;stroke:#ccf;fill:#ccf}#mermaid-svg-JIZpbKLfRTZV4Xfm .note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-JIZpbKLfRTZV4Xfm .noteText,#mermaid-svg-JIZpbKLfRTZV4Xfm .noteText>tspan{fill:#000;stroke:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .activation0{fill:#f4f4f4;stroke:#666}#mermaid-svg-JIZpbKLfRTZV4Xfm .activation1{fill:#f4f4f4;stroke:#666}#mermaid-svg-JIZpbKLfRTZV4Xfm .activation2{fill:#f4f4f4;stroke:#666}#mermaid-svg-JIZpbKLfRTZV4Xfm .mermaid-main-font{font-family:"trebuchet ms", verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .section{stroke:none;opacity:0.2}#mermaid-svg-JIZpbKLfRTZV4Xfm .section0{fill:rgba(102,102,255,0.49)}#mermaid-svg-JIZpbKLfRTZV4Xfm .section2{fill:#fff400}#mermaid-svg-JIZpbKLfRTZV4Xfm .section1,#mermaid-svg-JIZpbKLfRTZV4Xfm .section3{fill:#fff;opacity:0.2}#mermaid-svg-JIZpbKLfRTZV4Xfm .sectionTitle0{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .sectionTitle1{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .sectionTitle2{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .sectionTitle3{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .sectionTitle{text-anchor:start;font-size:11px;text-height:14px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .grid .tick{stroke:#d3d3d3;opacity:0.8;shape-rendering:crispEdges}#mermaid-svg-JIZpbKLfRTZV4Xfm .grid .tick text{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .grid path{stroke-width:0}#mermaid-svg-JIZpbKLfRTZV4Xfm .today{fill:none;stroke:red;stroke-width:2px}#mermaid-svg-JIZpbKLfRTZV4Xfm .task{stroke-width:2}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText{text-anchor:middle;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText:not([font-size]){font-size:11px}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutsideRight{fill:#000;text-anchor:start;font-size:11px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutsideLeft{fill:#000;text-anchor:end;font-size:11px}#mermaid-svg-JIZpbKLfRTZV4Xfm .task.clickable{cursor:pointer}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutsideLeft.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutsideRight.clickable{cursor:pointer;fill:#003163 !important;font-weight:bold}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText0,#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText1,#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText2,#mermaid-svg-JIZpbKLfRTZV4Xfm .taskText3{fill:#fff}#mermaid-svg-JIZpbKLfRTZV4Xfm .task0,#mermaid-svg-JIZpbKLfRTZV4Xfm .task1,#mermaid-svg-JIZpbKLfRTZV4Xfm .task2,#mermaid-svg-JIZpbKLfRTZV4Xfm .task3{fill:#8a90dd;stroke:#534fbc}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutside0,#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutside2{fill:#000}#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutside1,#mermaid-svg-JIZpbKLfRTZV4Xfm .taskTextOutside3{fill:#000}#mermaid-svg-JIZpbKLfRTZV4Xfm .active0,#mermaid-svg-JIZpbKLfRTZV4Xfm .active1,#mermaid-svg-JIZpbKLfRTZV4Xfm .active2,#mermaid-svg-JIZpbKLfRTZV4Xfm .active3{fill:#bfc7ff;stroke:#534fbc}#mermaid-svg-JIZpbKLfRTZV4Xfm .activeText0,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeText1,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeText2,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeText3{fill:#000 !important}#mermaid-svg-JIZpbKLfRTZV4Xfm .done0,#mermaid-svg-JIZpbKLfRTZV4Xfm .done1,#mermaid-svg-JIZpbKLfRTZV4Xfm .done2,#mermaid-svg-JIZpbKLfRTZV4Xfm .done3{stroke:grey;fill:#d3d3d3;stroke-width:2}#mermaid-svg-JIZpbKLfRTZV4Xfm .doneText0,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneText1,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneText2,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneText3{fill:#000 !important}#mermaid-svg-JIZpbKLfRTZV4Xfm .crit0,#mermaid-svg-JIZpbKLfRTZV4Xfm .crit1,#mermaid-svg-JIZpbKLfRTZV4Xfm .crit2,#mermaid-svg-JIZpbKLfRTZV4Xfm .crit3{stroke:#f88;fill:red;stroke-width:2}#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCrit0,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCrit1,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCrit2,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCrit3{stroke:#f88;fill:#bfc7ff;stroke-width:2}#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCrit0,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCrit1,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCrit2,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCrit3{stroke:#f88;fill:#d3d3d3;stroke-width:2;cursor:pointer;shape-rendering:crispEdges}#mermaid-svg-JIZpbKLfRTZV4Xfm .milestone{transform:rotate(45deg) scale(0.8, 0.8)}#mermaid-svg-JIZpbKLfRTZV4Xfm .milestoneText{font-style:italic}#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCritText0,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCritText1,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCritText2,#mermaid-svg-JIZpbKLfRTZV4Xfm .doneCritText3{fill:#000 !important}#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCritText0,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCritText1,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCritText2,#mermaid-svg-JIZpbKLfRTZV4Xfm .activeCritText3{fill:#000 !important}#mermaid-svg-JIZpbKLfRTZV4Xfm .titleText{text-anchor:middle;font-size:18px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm g.classGroup text{fill:#9370db;stroke:none;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family);font-size:10px}#mermaid-svg-JIZpbKLfRTZV4Xfm g.classGroup text .title{font-weight:bolder}#mermaid-svg-JIZpbKLfRTZV4Xfm g.clickable{cursor:pointer}#mermaid-svg-JIZpbKLfRTZV4Xfm g.classGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-JIZpbKLfRTZV4Xfm g.classGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm .classLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5}#mermaid-svg-JIZpbKLfRTZV4Xfm .classLabel .label{fill:#9370db;font-size:10px}#mermaid-svg-JIZpbKLfRTZV4Xfm .relation{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .dashed-line{stroke-dasharray:3}#mermaid-svg-JIZpbKLfRTZV4Xfm #compositionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #compositionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #aggregationStart{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #aggregationEnd{fill:#ECECFF;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #dependencyStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #dependencyEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #extensionStart{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm #extensionEnd{fill:#9370db;stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm .commit-id,#mermaid-svg-JIZpbKLfRTZV4Xfm .commit-msg,#mermaid-svg-JIZpbKLfRTZV4Xfm .branch-label{fill:lightgrey;color:lightgrey;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .pieTitleText{text-anchor:middle;font-size:25px;fill:#000;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .slice{font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm g.stateGroup text{fill:#9370db;stroke:none;font-size:10px;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm g.stateGroup text{fill:#9370db;fill:#333;stroke:none;font-size:10px}#mermaid-svg-JIZpbKLfRTZV4Xfm g.statediagram-cluster .cluster-label text{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm g.stateGroup .state-title{font-weight:bolder;fill:#000}#mermaid-svg-JIZpbKLfRTZV4Xfm g.stateGroup rect{fill:#ECECFF;stroke:#9370db}#mermaid-svg-JIZpbKLfRTZV4Xfm g.stateGroup line{stroke:#9370db;stroke-width:1}#mermaid-svg-JIZpbKLfRTZV4Xfm .transition{stroke:#9370db;stroke-width:1;fill:none}#mermaid-svg-JIZpbKLfRTZV4Xfm .stateGroup .composit{fill:white;border-bottom:1px}#mermaid-svg-JIZpbKLfRTZV4Xfm .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px}#mermaid-svg-JIZpbKLfRTZV4Xfm .state-note{stroke:#aa3;fill:#fff5ad}#mermaid-svg-JIZpbKLfRTZV4Xfm .state-note text{fill:black;stroke:none;font-size:10px}#mermaid-svg-JIZpbKLfRTZV4Xfm .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.7}#mermaid-svg-JIZpbKLfRTZV4Xfm .edgeLabel text{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .stateLabel text{fill:#000;font-size:10px;font-weight:bold;font-family:'trebuchet ms', verdana, arial;font-family:var(--mermaid-font-family)}#mermaid-svg-JIZpbKLfRTZV4Xfm .node circle.state-start{fill:black;stroke:black}#mermaid-svg-JIZpbKLfRTZV4Xfm .node circle.state-end{fill:black;stroke:white;stroke-width:1.5}#mermaid-svg-JIZpbKLfRTZV4Xfm #statediagram-barbEnd{fill:#9370db}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-cluster rect{fill:#ECECFF;stroke:#9370db;stroke-width:1px}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-cluster rect.outer{rx:5px;ry:5px}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-state .divider{stroke:#9370db}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-state .title-state{rx:5px;ry:5px}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-cluster.statediagram-cluster .inner{fill:white}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-cluster.statediagram-cluster-alt .inner{fill:#e0e0e0}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-cluster .inner{rx:0;ry:0}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-state rect.basic{rx:5px;ry:5px}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#efefef}#mermaid-svg-JIZpbKLfRTZV4Xfm .note-edge{stroke-dasharray:5}#mermaid-svg-JIZpbKLfRTZV4Xfm .statediagram-note rect{fill:#fff5ad;stroke:#aa3;stroke-width:1px;rx:0;ry:0}:root{--mermaid-font-family: '"trebuchet ms", verdana, arial';--mermaid-font-family: "Comic Sans MS", "Comic Sans", cursive}#mermaid-svg-JIZpbKLfRTZV4Xfm .error-icon{fill:#522}#mermaid-svg-JIZpbKLfRTZV4Xfm .error-text{fill:#522;stroke:#522}#mermaid-svg-JIZpbKLfRTZV4Xfm .edge-thickness-normal{stroke-width:2px}#mermaid-svg-JIZpbKLfRTZV4Xfm .edge-thickness-thick{stroke-width:3.5px}#mermaid-svg-JIZpbKLfRTZV4Xfm .edge-pattern-solid{stroke-dasharray:0}#mermaid-svg-JIZpbKLfRTZV4Xfm .edge-pattern-dashed{stroke-dasharray:3}#mermaid-svg-JIZpbKLfRTZV4Xfm .edge-pattern-dotted{stroke-dasharray:2}#mermaid-svg-JIZpbKLfRTZV4Xfm .marker{fill:#333}#mermaid-svg-JIZpbKLfRTZV4Xfm .marker.cross{stroke:#333}
:root { --mermaid-font-family: "trebuchet ms", verdana, arial;}</style>
<style>#mermaid-svg-JIZpbKLfRTZV4Xfm {
color: rgba(0, 0, 0, 0.75);
font: ;
}</style>
input
iteration 1
iteration 2
iteration 3
...
iteration N
output
總結
整體來說,在回圈體內呼叫異步函式有以下三種方法:
傳統 for回圈
最傳統的解決方案
Promise.all, await 和 map 的結合
可以近似同步地并行呼叫回圈體內的 API,如果需要在陣列之中回圈呼叫 API,并且 API 之間彼此沒有什么關聯,那么使用這個方案可以極大的提升用戶體驗感
for await...of
for of 的異步支持版本,可以串行呼叫 API,在不使用其他關鍵字的情況下與傳統的 for回圈 效果一樣
但是,因為 for of 是基于迭代器實作的,這也就代表著可以通過重寫迭代器去實作一些特殊的業務場景,如: