JavaScript实现异步任务循环顺序执行详解

 更新时间:2023年03月17日 09:08:50   作者:飞仔FeiZai  
这篇文章主要为大家详细介绍了JavaScript中实现异步任务循环顺序执行的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下

需求场景:数组的元素作为异步任务的参数,循环遍历该数组,并执行异步任务。

一、错误的实现

简单的错误实现

// 异步任务的参数数组
const arr = [1, 2, 3, 4];
// 异步任务函数
function task(params, callback) {
  setTimeout(() => {
    if (!!callback) {
      callback(params);
    }
  }, 1000);
}
// 循环遍历异步任务的参数数组,并执行异步任务
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");
    }
  });
});

执行结果输出:

由上图可知,所有异步任务的执行是同时开始,并同时结束的,并未按顺序先后执行。

使用 Promise.all 的错误实现

Promise.all() 是一个用于并行执行多个 Promise 的方法,当所有的 Promise 都成功执行后,它返回一个包含所有 Promise 结果的数组,如果其中任何一个 Promise 失败或出错,它将直接跳转到 catch 块中返回一个 rejected 状态的 Promise。

// 异步任务的参数数组
const arr = [1, 2, 3, 4];
// 异步任务函数
function task(params, callback) {
  setTimeout(() => {
    if (!!callback) {
      callback(params);
    }
  }, 1000);
}

const tasks = [];

// 循环遍历异步任务的参数数组,并执行异步任务
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);
  });

执行结果输出:

由上图可知,循环中的所有异步任务的执行是并行执行的,并未按顺序先后执行。因为 Promise.all() 方法的执行顺序是并行执行的,而不是按照 Promise 在数组中的顺序执行的。

二、正确的实现

// 异步任务的参数数组
const arr = [1, 2, 3, 4];
// 异步任务函数
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);
      });
    });
  });
});

// 定义一个递归函数来依次执行任务
function runTasks(index) {
  if (index >= tasks.length) {
    // 如果所有任务都已经执行完毕,返回一个 resolved 的 Promise
    return Promise.resolve();
  }

  // 执行当前任务,然后递归执行下一个任务
  return tasks[index]().then(function () {
    return runTasks(index + 1);
  });
}

// 调用递归函数来执行任务
runTasks(0)
  .then(function () {
    console.log("All tasks are done!");
  })
  .catch(function (error) {
    console.error(error);
  });

执行结果输出:

到此这篇关于JavaScript实现异步任务循环顺序执行详解的文章就介绍到这了,更多相关JavaScript异步任务循环顺序执行内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Javascript查询DBpedia小应用实例学习

    Javascript查询DBpedia小应用实例学习

    本文则尝试利用SPARQLWrapper.js来读取DBpedia的数据,并显示出来,感兴趣的你可以参考下,或许对你有所帮助
    2013-03-03
  • JS+Canvas实现五子棋游戏

    JS+Canvas实现五子棋游戏

    这篇文章主要为大家详细介绍了原生JS+Canvas实现五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • JS获取当前网址、主机地址项目根路径

    JS获取当前网址、主机地址项目根路径

    本文为大家提供JS如何获取当前网址、主机地址之后的目录及项目根路径的方法,喜欢的朋友可以收藏下
    2013-11-11
  • 极易被忽视的javascript面试题七问七答

    极易被忽视的javascript面试题七问七答

    这篇文章主要为大家详细介绍了一道极易被忽视的javascript面试题七问七答,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • javascript实现导航栏分页效果

    javascript实现导航栏分页效果

    这篇文章主要为大家详细介绍了javascript实现导航栏分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-06-06
  • Bootstrap table使用方法汇总

    Bootstrap table使用方法汇总

    这篇文章主要为大家总结了Bootstrap table简单使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • JavaScript数组类型Array相关的属性与方法详解

    JavaScript数组类型Array相关的属性与方法详解

    这篇文章主要给大家介绍了关于JavaScript数组类型Array相关的属性与方法的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • D3.js进阶系列之CSV表格文件的读取详解

    D3.js进阶系列之CSV表格文件的读取详解

    D3.js支持从外部读取数据进行图形交互(Loading External Resources),支持的格式有CSV、txt、Html、tsv、xml文本文件和JSON XML数据结构,下面这篇文章主要给大家介绍了D3.js中CSV表格文件读取的相关资料,需要的朋友可以参考下。
    2017-06-06
  • 纯js实现图片匀速淡入淡出效果

    纯js实现图片匀速淡入淡出效果

    这篇文章主要为大家详细介绍了纯js实现图片匀速淡入淡出效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • ionic2中使用自动生成器的方法

    ionic2中使用自动生成器的方法

    这篇文章主要介绍了ionic2中使用自动生成器的方法,需要的朋友可以参考下
    2018-03-03

最新评论