资讯专栏INFORMATION COLUMN

Promise异步函数顺序执行的四种方法

Awbeci / 2078人阅读

摘要:前几天遇到一个编程题,要求控制顺序执行,今天总结了一下这个至少有好四种方法都可以实现,包括嵌套,通过一个串起来,,实现,以下逐一介绍。

前几天遇到一个编程题,要求控制promise顺序执行,今天总结了一下这个至少有好四种方法都可以实现,包括promise嵌套,通过一个promise串起来,generator,async实现,以下逐一介绍。
原题目如下:
//实现mergePromise函数,把传进去的数组顺序先后执行,
//并且把返回的数据先后放到数组data中
const timeout = ms => new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve();
    }, ms);
});

const ajax1 = () => timeout(2000).then(() => {
    console.log("1");
    return 1;
});

const ajax2 = () => timeout(1000).then(() => {
    console.log("2");
    return 2;
});

const ajax3 = () => timeout(2000).then(() => {
    console.log("3");
    return 3;
});

function mergePromise(ajaxArray) {
    //todo 补全函数
}

mergePromise([ajax1, ajax2, ajax3]).then(data => {
    console.log("done");
    console.log(data); // data 为 [1, 2, 3]
});

// 分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]
一. promise嵌套
function mergePromise1(ajaxArray) {
  let arr = [];
    return ajaxArray[0]().then(data=>{
        arr.push(data);
        return ajaxArray[1]();
    }).then(data=>{
        arr.push(data);
        return ajaxArray[2]();
    }).then(data=>{
      arr.push(data);
      return arr;
    });
}
二. Promise.resolve将promise串连成一个任务队列
function mergePromise2(ajaxArray) {
  let p = Promise.resolve();
  let arr = [];
  ajaxArray.forEach(promise => {
    p = p.then(promise).then((data) => {
        arr.push(data);
        return arr;
    });
  });
  return p;
}

此方法相对于上面的方法简单并且书写直观易懂,还有一种类似的任务队列,将数组按顺序从左边头部取出一个执行,执行完成后触发自定义next方法,next方法负责从数组中取出下一个任务执行。

三. generator函数 1. 原生generator函数
var mergePromise3 = function* (ajaxArray) {
  let p1 = yield ajaxArray[0]();
  let p2 = yield ajaxArray[1]();
  let p3 = yield ajaxArray[2]();
  return Promise.resolve([p1,p2,p3]);
}

//自动运行的run
function run(fn) {
  return new Promise((resolve, reject) => {
    var g = fn;
    let arr = [];
    function next(preData) {
      if(preData) { //如果有数据则push进数组
        arr.push(preData); 
      }
      let result = g.next(preData); //获取每一步执行结果,其中value为promise对象,done表示是否执行完成
      if (result.done) { //函数执行完毕则resolve数组
        resolve(arr);
      }
      else { //函数没有执行完毕则递归执行
          result.value.then(function(nowData) {
            next(nowData);
          });
      }
    }
    next();
  });
}
使用这种方法需要修改mergePromise方法为:
run(mergePromise3([ajax1, ajax2, ajax3])).then(data => {
  console.log("done");
  console.log(data); // data 为 [1, 2, 3]
});
2. 利用co模块自动执行
const co = require("co")
  co(mergePromise3([ajax1, ajax2, ajax3])).then(data => {
  console.log("done");
  console.log(data); // data 为 [1, 2, 3]
});

此方法原理和上面一样,只是使用已有的封装好的co模块来自动执行

四. async函数
function mergePromise4(ajaxArray) {
  let arr = [];
  async function run() {
      for(let p of ajaxArray) {
          let val = await p();
          arr.push(val);
      }
      return arr;
  }
  return run();
}

以上列出了四种方法,具体使用那种方法也根据喜好而定,如果有其他的好的方法欢迎留言补充。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/97010.html

相关文章

  • JavaScript 异步编程四种方式

    摘要:异步编程是每个使用编程的人都会遇到的问题,无论是前端的请求,或是的各种异步。本文就来总结一下常见的四种处理异步编程的方法。利用一种链式调用的方法来组织异步代码,可以将原来以回调函数形式调用的代码改为链式调用。 异步编程是每个使用 JavaScript 编程的人都会遇到的问题,无论是前端的 ajax 请求,或是 node 的各种异步 API。本文就来总结一下常见的四种处理异步编程的方法。...

    microelec 评论0 收藏0
  • Promise 四种常用方法

    摘要:前言看到项目里不少人用了的库类,比如等方式,使用的时候翻看长长的文档,真心累觉不爱。用法常用三个场景。处理异步回调多个异步函数同步处理异步依赖异步回调封装统一的入口办法或者错误处理处理异步回调的基本用法,处理异步回调。 前言 看到项目里不少人用了Promise 的库类,比如 bluebird、q 、jQuery.Deffered 等 polyfill promise 方式,使用的时候...

    wangzy2019 评论0 收藏0
  • promise用法解析

    摘要:这时,第二个方法指定的回调函数,就会等待这个新的对象状态发生变化。 1.概述 javascript是单线程语言(单线程/多线程、阻塞/非阻塞、同步、异步)参考此文章,所有的任务都是按顺序执行的,但是对于很耗时的操作采用异步的方式(前一个任务结束的时候,不是执行下一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行)参考此文章,js中异步编程的四种方法:回调函数、事件监听、...

    fai1017 评论0 收藏0
  • 关于promise的小结

    摘要:则是把类似的异步处理对象和处理规则进行规范化,并按照采用统一的接口来编写,而采取规定方法之外的写法都会出错。这个对象有一个方法,指定回调函数,用于在异步操作执行完后执行回调函数处理。到目前为止,已经学习了创建对象和用,方法来注册回调函数。 Promise 本文从js的异步处理出发,引入Promise的概念,并且介绍Promise对象以及其API方法。 js里的异步处理 可以参考这篇文章...

    Tony_Zby 评论0 收藏0
  • 前端异步解决方案-3(Promise

    摘要:又有好些天没有动笔了,这几天一直在断断续续的学习和,今天终于能够把着两个玩意结合起来了解决异步问题了。今天我先把相关的用法和对异步的处理分享给大家。老样子,还是先模拟一个。 又有好些天没有动笔了,这几天一直在断断续续的学习Promise和generator,今天终于能够把着两个玩意结合起来了解决异步问题了。今天我先把promise相关的用法和对异步的处理分享给大家。老样子,还是先模拟一...

    genedna 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<