周總結(jié)-JS依次執(zhí)行多項(xiàng)異步任務(wù)

1、JS依次執(zhí)行多項(xiàng)異步任務(wù)

  • 有時(shí)候,我們希望批量執(zhí)行一組異步任務(wù),但是不是并行,而是依次執(zhí)行,這組任務(wù)是動(dòng)態(tài)的,在一個(gè)數(shù)組里,當(dāng)然我們可以用 for 循環(huán)然后一個(gè)一個(gè) await 執(zhí)行,但是還有另外一種方式:
async function taskReducer(promise, action){
  let res = await promise;
  return action(res);
}

function sleep(ms){
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function asyncTask(i){
  await sleep(500);
  console.log(`task ${i} done`);
  return ++i;
}


[asyncTask, asyncTask, asyncTask].reduce(taskReducer, 0);

在上面的例子里,我們定義了一個(gè) taskReducer:

async function taskReducer(promise, action){
  let res = await promise;
  return action(res);
}

這個(gè) reducer 的兩個(gè)參數(shù)是 promise 和 action,promise 是代表當(dāng)前任務(wù)的 promise,而 action 是下一個(gè)要執(zhí)行的任務(wù)。我們可以 await 當(dāng)前 promise 執(zhí)行當(dāng)前任務(wù),然后將執(zhí)行結(jié)果傳給下一個(gè) action 就可以了。

這樣我們可以調(diào)用:

[task1, task2, task3, ...].reduce(taskReducer, init);

不管這些任務(wù)是同步還是異步都可以被依次執(zhí)行。需要注意的是,每一個(gè)任務(wù)的返回值將是下一個(gè)任務(wù)的輸入 promise 或者 value。

2、generator 與 async/await 一同使用

將上面的代碼進(jìn)一步擴(kuò)展,我們發(fā)現(xiàn),它可以支持 generator 與 async/await 一同使用:

async function reducer(promise, action){
  let res = await promise;
  return action(res);
}

function tick(i){
  console.log(i);
  return new Promise(resolve => setTimeout(()=>resolve(++i), 1000));
}

function continuous(...functors){
  return async function(input){
    return await functors.reduce(reducer, input)
  }
}

function * timing(count = 5){
  for(let i = 0; i < count; i++){
    yield tick;
  }
}

continuous(...timing(10))(0);

在上面的例子里,我們定義了一個(gè)計(jì)時(shí) tick 函數(shù),我們通過(guò) timing 來(lái)連續(xù)調(diào)用它,而 timing 是一個(gè) generator,計(jì)時(shí)器顯然是異步函數(shù),然而我們可以:

continuous(...timing(10))(0);

而這里的 continuous 其實(shí)就是前面的 reduce 的封裝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 異步編程對(duì)JavaScript語(yǔ)言太重要。Javascript語(yǔ)言的執(zhí)行環(huán)境是“單線程”的,如果沒(méi)有異步編程,根本...
    呼呼哥閱讀 7,399評(píng)論 5 22
  • 弄懂js異步 講異步之前,我們必須掌握一個(gè)基礎(chǔ)知識(shí)-event-loop。 我們知道JavaScript的一大特點(diǎn)...
    DCbryant閱讀 2,868評(píng)論 0 5
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 6,445評(píng)論 9 19
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 8,771評(píng)論 0 29
  • 你不知道JS:異步 第三章:Promises 接上篇3-1 錯(cuò)誤處理(Error Handling) 在異步編程中...
    purple_force閱讀 1,488評(píng)論 0 2

友情鏈接更多精彩內(nèi)容