JavaScript如何实现promise顺序执行返回结果存放在数组
沉沙 2018-08-09 来源 : 阅读 2486 评论 0

摘要:本篇教程介绍了JavaScript如何实现promise顺序执行返回结果存放在数组,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

本篇教程介绍了JavaScript如何实现promise顺序执行返回结果存放在数组,希望阅读本篇文章以后大家有所收获,帮助大家对JavaScript的理解更加深入。

<

一个编程题:三个返回promise对象的异步操作,让你写一个函数可以将这些操作顺序执行,并返回一个数组包含三个异步对象的结果
异步对象:

// 异步函数a
var a = function () {
  return new Promise(function (resolve, reject) {
      console.log("a")
    setTimeout(function () {
      resolve('a')
    }, 1000)
  })
}

// 异步函数b
var b = function () {
  return new Promise(function (resolve, reject) {
      console.log("b")
    resolve('b')
  })
}

// 异步函数c
var c = function () {
  return new Promise(function (resolve, reject) {
      console.log("c")
    setTimeout(function () {
      resolve('c')
    }, 500)
  })
}

注意:promise对象在实例化的时候就会执行,所以函数都是返回promise对象,这样执行函数的时候就会执行promise对象中的内容
我们期望的结果是:

//a
//b
//c
//(3) ["a", "b", "c"]
//done


所以关键是怎么顺序执行promise并把结果一个一个塞到数组里
注意promise对象是不能直接得到resolve传来的结果的,一般的方式是.then里面写resolve的回调函数,所以刚才的需求可以这样写

var mergePromise = async function mergePromise(arr) {
    var mergedAjax = Promise.resolve()
    var data = [] ;
    for(let promise of arr){
        mergedAjax = mergedAjax.then(()=>{
            return promise().then(val=>{
                data.push(val)
            })
        })
    }
    return mergedAjax.then(()=>{
        return data
    })
};

mergePromise([a,b,c]).then(function (data) {
    console.log(data);
    console.log("done");
});

还有这种写法:

var mergePromise = async function mergePromise(arr) {
    var mergedAjax = Promise.resolve()
    var data = [] ;
    for(let promise of arr){
        mergedAjax = mergedAjax.then((val)=>{
            if(val)data.push(val)
            return promise()
        })
    }
    return mergedAjax.then((val)=>{
        data.push(val)
        return data
    })
};

mergePromise(ajaxArray).then(function (data) {
    console.log(data);
    console.log("done");
});

以上两种其实是一个then的链式调用,最后返回收集了异步结果的数组
 
这个需求用asnyc await的写法就比较好看和直观

async function queue(arr) {
  let data = []
  for (let promise of arr) {
    let res = await promise()
    data.push(res)
  }
  return data
}
queue([a, b, c])
  .then(data => {
    console.log(data)    console.log("done");
});

感觉上是返回了一个data数组,应该会报没有.then方法的错误,然而实际上是返回了一个Promise.resolve(data)
至于为什么能将resolve的值抽离出来,是应为await是generator的语法糖,比如一个asnyc函数:

async function myfn(arr) {    let res = await a()    console.log(res)    res = await b()    console.log(res)    res = await c()    console.log(res)}

myfn([a,b,c])

其实等价于自动执行的generator函数

function spawn(genF) {
  return new Promise(function(resolve, reject) {
    const gen = genF();
    function step(nextF) {

      let next;
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if(next.done) {
        return resolve(next.value);
      }
      Promise.resolve(next.value).then(function(v) {
          //Promise.resolve(next.value)中next.value是一个promise对象,比如a()生成的
          //Promise.resolve(arg)中arg是一个promise对象时,将会原封不动返回这个对象
        step(function() { return gen.next(v); });//这里gen.next(v)执行赋值操作 let res = v 也就是为什么async方法能得到promise中resolve的值
        
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}

function fn(args) {
  return spawn(function* () {
    let res = yield a()
    console.log(res)
    res = yield b()
    console.log(res)
    res = yield c()
    console.log(res)
  });
}

fn()

 
最后说一下,如果要让异步操作并发,可以用promise自带的all方法    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标WEB前端JavaScript频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程