溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行

發(fā)布時間:2023-03-17 10:46:41 來源:億速云 閱讀:123 作者:iii 欄目:開發(fā)技術

今天小編給大家分享一下JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行的相關知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    需求場景:數(shù)組的元素作為異步任務的參數(shù),循環(huán)遍歷該數(shù)組,并執(zhí)行異步任務。

    一、錯誤的實現(xiàn)

    簡單的錯誤實現(xiàn)

    // 異步任務的參數(shù)數(shù)組
    const arr = [1, 2, 3, 4];
    // 異步任務函數(shù)
    function task(params, callback) {
      setTimeout(() => {
        if (!!callback) {
          callback(params);
        }
      }, 1000);
    }
    // 循環(huán)遍歷異步任務的參數(shù)數(shù)組,并執(zhí)行異步任務
    console.time("Test code");
    arr.forEach((item, index) => {
      task(item, (ret) => {
        console.log("ret", ret);
        console.timeEnd("Test code");
    
        if (index + 1 < arr.length) {
          console.time("Test code");
        }
      });
    });

    執(zhí)行結果輸出:

    JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行

    由上圖可知,所有異步任務的執(zhí)行是同時開始,并同時結束的,并未按順序先后執(zhí)行。

    使用 Promise.all 的錯誤實現(xiàn)

    Promise.all() 是一個用于并行執(zhí)行多個 Promise 的方法,當所有的 Promise 都成功執(zhí)行后,它返回一個包含所有 Promise 結果的數(shù)組,如果其中任何一個 Promise 失敗或出錯,它將直接跳轉(zhuǎn)到 catch 塊中返回一個 rejected 狀態(tài)的 Promise。

    // 異步任務的參數(shù)數(shù)組
    const arr = [1, 2, 3, 4];
    // 異步任務函數(shù)
    function task(params, callback) {
      setTimeout(() => {
        if (!!callback) {
          callback(params);
        }
      }, 1000);
    }
    
    const tasks = [];
    
    // 循環(huán)遍歷異步任務的參數(shù)數(shù)組,并執(zhí)行異步任務
    console.time("Test code");
    arr.forEach((item, index) => {
      tasks.push(
        new Promise((resolve) => {
          task(item, (ret) => {
            console.log("ret", ret);
            console.timeEnd("Test code");
    
            if (index + 1 < arr.length) {
              console.time("Test code");
            }
            resolve(ret);
          });
        })
      );
    });
    
    Promise.all(tasks)
      .then((values) => {
        console.log(values);
      })
      .catch((error) => {
        console.error(error);
      });

    執(zhí)行結果輸出:

    JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行

    由上圖可知,循環(huán)中的所有異步任務的執(zhí)行是并行執(zhí)行的,并未按順序先后執(zhí)行。因為 Promise.all() 方法的執(zhí)行順序是并行執(zhí)行的,而不是按照 Promise 在數(shù)組中的順序執(zhí)行的。

    二、正確的實現(xiàn)

    // 異步任務的參數(shù)數(shù)組
    const arr = [1, 2, 3, 4];
    // 異步任務函數(shù)
    function task(params, callback) {
      setTimeout(() => {
        if (!!callback) {
          callback(params);
        }
      }, 1000);
    }
    
    const tasks = [];
    
    console.time("Test code");
    arr.forEach((item, index) => {
      tasks.push(function () {
        return new Promise((resolve) => {
          task(item, (ret) => {
            console.log("ret", ret);
            console.timeEnd("Test code");
            if (index + 1 < arr.length) {
              console.time("Test code");
            }
            resolve(ret);
          });
        });
      });
    });
    
    // 定義一個遞歸函數(shù)來依次執(zhí)行任務
    function runTasks(index) {
      if (index >= tasks.length) {
        // 如果所有任務都已經(jīng)執(zhí)行完畢,返回一個 resolved 的 Promise
        return Promise.resolve();
      }
    
      // 執(zhí)行當前任務,然后遞歸執(zhí)行下一個任務
      return tasks[index]().then(function () {
        return runTasks(index + 1);
      });
    }
    
    // 調(diào)用遞歸函數(shù)來執(zhí)行任務
    runTasks(0)
      .then(function () {
        console.log("All tasks are done!");
      })
      .catch(function (error) {
        console.error(error);
      });

    執(zhí)行結果輸出:

    JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行

    以上就是“JavaScript如何實現(xiàn)異步任務循環(huán)順序執(zhí)行”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業(yè)資訊頻道。

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

    AI