Javascript異步流程控制之串行執(zhí)行詳解
這篇文章主要講一下如何串行執(zhí)行一組異步任務(wù),例如有下面幾個(gè)任務(wù),在這里我們用setTimeout模擬一個(gè)異步任務(wù):
let taskA = () => setTimeout(() => console.log('run task A'), 100);
let taskB = () => setTimeout(() => console.log('run task B'), 50);
let taskC = () => setTimeout(() => console.log('run task C'), 150);
直接運(yùn)行
taskA(); taskB(); taskC();
是達(dá)不到順序執(zhí)行A,B,C 的三個(gè)任務(wù)的效果的。
首先我們看一下最傳統(tǒng)的做法,通過(guò)回調(diào)的方式在一個(gè)任務(wù)執(zhí)行完成之后調(diào)用下一個(gè)任務(wù):
let taskA = setTimeout(() => {
console.log('run task A');
taskB();
}, 100);
let taskB = setTimeout(() => {
console.log('run task B');
taskC();
}, 50);
let taskC = setTimeout(() => {
console.log('run task B');
}, 150);
第二種方法是將每一個(gè)任務(wù)封裝成一個(gè)返回Promise的函數(shù), 然后使用使用Promise的鏈?zhǔn)秸{(diào)用達(dá)到串行執(zhí)行的目的:
let taskA = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('run task A');
resolve();
}, 100);
})
let taskB = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('run task B');
resolve();
}, 50);
})
let taskC = () => new Promise((resolve, reject) => {
setTimeout(() => {
console.log('run task C');
resolve();
}, 150);
})
function runTasks2() {
console.log('tasks 2');
taskA().then(taskB).then(taskC);
}
假設(shè)任務(wù)的數(shù)量不確定,可以通過(guò)下面的方式來(lái)執(zhí)行:
function runTasks3(tasks) {
console.log('tasks 3');
let pro = tasks[0]();
for (let i = 1; i < tasks.length; i++) {
pro.then(tasks[i]);
}
}
借助于es7的async和await,我們還可以對(duì)上面的函數(shù)一種寫(xiě)法:
async function runTasks3_1(tasks) {
for (let i = 0; i < tasks.length; i++) {
await tasks[i]();
}
}
在文章的最后我們自己來(lái)實(shí)現(xiàn)一個(gè)串行執(zhí)行器, 用于執(zhí)行一組串行任務(wù):
function async(tasks) {
const count = tasks.length;
let index = 0;
const next = () => {
if (index >= count) return;
const task = tasks[index++];
task(next);
}
next(0);
}
函數(shù)的使用方式如下:
async([
next => setTimeout(() => { console.log('taskA ...'); next() }, 100),
next => setTimeout(() => { console.log('taskB ...'); next() }, 50),
next => setTimeout(() => { console.log('taskC ...'); next() }, 30)
]);
在每一個(gè)子任務(wù)中我們通過(guò)調(diào)用next函數(shù)繼續(xù)執(zhí)行下一個(gè)子任務(wù)。
在具體的使用中可能會(huì)遇到函數(shù)之間傳遞參數(shù)的情況,即前一個(gè)任務(wù)的執(zhí)行結(jié)果需要作為下一個(gè)任務(wù)的入?yún)?,這些都可以對(duì)上面的例子稍作修改就可以了~~
到此這篇關(guān)于Javascript異步流程控制之串行執(zhí)行詳解的文章就介紹到這了,更多相關(guān)Javascript串行執(zhí)行內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用json對(duì)象轉(zhuǎn)化為key,value的對(duì)象數(shù)組
這篇文章主要介紹了使用json對(duì)象轉(zhuǎn)化為key,value的對(duì)象數(shù)組方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06
JS中檢測(cè)數(shù)據(jù)類(lèi)型的幾種方式及優(yōu)缺點(diǎn)小結(jié)
這篇文章主要介紹了JS中檢測(cè)數(shù)據(jù)類(lèi)型的幾種方式及優(yōu)缺點(diǎn)小結(jié),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-12-12
JavaScript創(chuàng)建閉包的兩種方式的優(yōu)劣與區(qū)別分析
這篇文章主要介紹了JavaScript創(chuàng)建閉包的兩種方式的優(yōu)劣與區(qū)別分析的相關(guān)資料,需要的朋友可以參考下2015-06-06
JS基于FileSaver.js插件實(shí)現(xiàn)文件保存功能示例
這篇文章主要介紹了JS基于FileSaver.js插件實(shí)現(xiàn)文件保存功能,結(jié)合實(shí)例形式演示了FileSaver.js插件的具體使用技巧,需要的朋友可以參考下2016-12-12
原生js實(shí)現(xiàn)移動(dòng)端觸摸輪播的示例代碼
下面小編就為大家分享一篇原生js實(shí)現(xiàn)移動(dòng)端觸摸輪播的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12
SOSO地圖API使用(一)在地圖上畫(huà)圓實(shí)現(xiàn)思路與代碼
最近在做SOSO地圖相關(guān)開(kāi)發(fā),遇到相關(guān)畫(huà)圓知識(shí),特此簡(jiǎn)單記錄下來(lái),接下來(lái)講解如何在在地圖上畫(huà)圓,感興趣的朋友可以了解下2013-01-01

