Javascript異步流程控制之串行執(zhí)行詳解
這篇文章主要講一下如何串行執(zhí)行一組異步任務(wù),例如有下面幾個任務(wù),在這里我們用setTimeout模擬一個異步任務(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 的三個任務(wù)的效果的。
首先我們看一下最傳統(tǒng)的做法,通過回調(diào)的方式在一個任務(wù)執(zhí)行完成之后調(diào)用下一個任務(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);
第二種方法是將每一個任務(wù)封裝成一個返回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ù)量不確定,可以通過下面的方式來執(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,我們還可以對上面的函數(shù)一種寫法:
async function runTasks3_1(tasks) { for (let i = 0; i < tasks.length; i++) { await tasks[i](); } }
在文章的最后我們自己來實(shí)現(xiàn)一個串行執(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) ]);
在每一個子任務(wù)中我們通過調(diào)用next函數(shù)繼續(xù)執(zhí)行下一個子任務(wù)。
在具體的使用中可能會遇到函數(shù)之間傳遞參數(shù)的情況,即前一個任務(wù)的執(zhí)行結(jié)果需要作為下一個任務(wù)的入?yún)?,這些都可以對上面的例子稍作修改就可以了~~
到此這篇關(guān)于Javascript異步流程控制之串行執(zhí)行詳解的文章就介紹到這了,更多相關(guān)Javascript串行執(zhí)行內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)的二級橫向菜單條實(shí)例
這篇文章主要介紹了js實(shí)現(xiàn)的二級橫向菜單條,是非常美觀簡潔的二級導(dǎo)航條效果,可實(shí)現(xiàn)針對鼠標(biāo)事件的動態(tài)響應(yīng)及頁面樣式切換功能,簡單實(shí)用,需要的朋友可以參考下2015-08-08js中requestAnimationFrame()解讀與使用示例
requestAnimationFrame()是JavaScript中用于創(chuàng)建高效、流暢動畫的核心方法,它與瀏覽器的重繪過程同步,確保每次動畫更新都與顯示器刷新率同步,下面就來一起了解一下2024-09-09JavaScript實(shí)現(xiàn)簡單的隱藏式側(cè)邊欄功能示例
這篇文章主要介紹了JavaScript實(shí)現(xiàn)簡單的隱藏式側(cè)邊欄功能,涉及javascript結(jié)合定時器針對頁面元素屬性動態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-08-08Javascript防止圖片拉伸的自適應(yīng)處理方法
這篇文章主要給大家介紹了關(guān)于利用Javascript防止圖片拉伸的自適應(yīng)處理方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12