js非同步操作的流程控制——20181114
阿新 • • 發佈:2018-12-06
序列執行(程式碼可直接在console控制檯執行)
var items = [ 1, 2, 3, 4, 5, 6 ]; var results = []; function async(arg, callback) { console.log('引數為 ' + arg +' , 1秒後返回結果'); setTimeout(function () { callback(arg * 2); }, 1000); } function final(value) { console.log('完成: ', value); } function series(item) { if(item) { console.log('lalala'); async( item, function(result) { console.log('bbb'); results.push(result); console.log(result); return series(items.shift()); }); } else { return final(results[results.length - 1]); } } series(items.shift());
上面的寫法需要六秒,才能完成整個指令碼。
並行執行
var items = [ 1, 2, 3, 4, 5, 6 ]; var results = []; function async(arg, callback) { console.log('引數為 ' + arg +' , 1秒後返回結果'); setTimeout(function () { callback(arg * 2); }, 1000); } function final(value) { console.log('完成: ', value); } items.forEach(function(item) { async(item, function(result){ console.log('bbb'); results.push(result); console.log(result); if(results.length === items.length) { final(results[results.length - 1]); } }) });
上面程式碼中,forEach
方法會同時發起六個非同步任務,等到它們全部完成以後,才會執行final
函式。
相比而言,上面的寫法只要一秒,就能完成整個指令碼。這就是說,並行執行的效率較高,比起序列執行一次只能執行一個任務,較為節約時間。但是問題在於如果並行的任務較多,很容易耗盡系統資源,拖慢執行速度。因此有了第三種流程控制方式。
並行與序列的結合
所謂並行與序列的結合,就是設定一個門檻,每次最多隻能並行執行n
個非同步任務,這樣就避免了過分佔用系統資源。
var items = [ 1, 2, 3, 4, 5, 6 ]; var results = []; var running = 0; var limit = 2; function async(arg, callback) { console.log('引數為 ' + arg +' , 1秒後返回結果'); setTimeout(function () { callback(arg * 2); }, 1000); } function final(value) { console.log('完成: ', value); } function launcher() { while(running < limit && items.length > 0) { var item = items.shift(); async(item, function(result) { results.push(result); running--; if(items.length > 0) { launcher(); } else if(running == 0) { final(results); } }); running++; } } launcher();