设为首页收藏本站

IT技术擎 - 最棒的IT web技术交流社区

 找回密码
 注册为IT技术擎人

QQ登录

只需一步,快速开始

搜索
热搜: php h5 jquery
查看: 10|回复: 0

[未分类] promise顺序执行,返回结果存放在数组

[复制链接]
发表于 2018-8-10 20:05:19 | 显示全部楼层 |阅读模式
遇到面试的一个编程题:三个返回promise对象的异步操作,让你写一个函数可以将这些操作顺序执行,并返回一个数组包含三个异步对象的结果
异步对象:
  1. //异步函数a
  2. vara =function () {returnnewPromise(function (resolve, reject) { console.log("a") setTimeout(function () { resolve('a') }, 1000) })
  3. }
  4. //异步函数b
  5. varb =function () {returnnewPromise(function (resolve, reject) { console.log("b") resolve('b') })
  6. }
  7. //异步函数c
  8. varc =function () {returnnewPromise(function (resolve, reject) { console.log("c") setTimeout(function () { resolve('c') }, 500) })
  9. }
复制代码
注意:promise对象在实例化的时候就会执行,所以函数都是返回promise对象,这样执行函数的时候就会执行promise对象中的内容
我们期望的结果是:
  1. //a
  2. //b
  3. //c
  4. //(3) ["a", "b", "c"]
  5. //done
复制代码
所以关键是怎么顺序执行promise并把结果一个一个塞到数组里
注意promise对象是不能直接得到resolve传来的结果的,一般的方式是.then里面写resolve的回调函数,所以刚才的需求可以这样写
  1. varmergePromise = asyncfunction mergePromise(arr) {varmergedAjax =Promise.resolve() vardata =[] ;for(let promise of arr){ mergedAjax = mergedAjax.then(()= >{returnpromise().then(val= >{ data.push(val) }) }) }returnmergedAjax.then(()= >{returndata })
  2. };
  3. mergePromise([a,b,c]).then(function (data) { console.log(data); console.log("done");
  4. });
复制代码
还有这种写法:
  1. varmergePromise = async functionmergePromise(arr) {varmergedAjax =Promise.resolve() vardata =[] ;for(let promise of arr){ mergedAjax = mergedAjax.then((val)= >{if(val)data.push(val) returnpromise() }) }returnmergedAjax.then((val)= >{ data.push(val) returndata })
  2. };
  3. mergePromise(ajaxArray).then(function(data) { console.log(data); console.log("done");
  4. });
复制代码
以上两种其实是一个then的链式调用,最后返回收集了异步结果的数组
这个需求用asnyc await的写法就比较好看和直观
  1. asyncfunction queue(arr) { let data =[] for(let promise of arr) { let res = awaitpromise() data.push(res) }returndata
  2. }
  3. queue([a, b, c]) .then(data = >{ console.log(data)<br> console.log("done");
复制代码
  1. });
复制代码
感觉上是返回了一个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)}
  1. [/code]
  2. myfn([a,b,c])
  3. 其实等价于自动执行的generator函数
  4. [code]
  5. functionspawn(genF) {returnnewPromise(function(resolve, reject) { const gen =genF();functionstep(nextF) {
  6. let next;try{ next =nextF(); }catch(e) {returnreject(e); }if(next.done) {returnresolve(next.value); } Promise.resolve(next.value).then(function(v) {//Promise.resolve(next.value)中next.value是一个promise对象,比如a()生成的 //Promise.resolve(arg)中arg是一个promise对象时,将会原封不动返回这个对象 step(function() { returngen.next(v); });//这里gen.next(v)执行赋值操作 let res = v 也就是为什么async方法能得到promise中resolve的值 }, function(e) { step(function() { returngen.throw(e); }); }); } step(function() { returngen.next(undefined); }); });
  7. }
  8. functionfn(args) {returnspawn(function*() { let res =yield a() console.log(res) res =yield b() console.log(res) res =yield c() console.log(res) });
  9. }
  10. fn()
复制代码

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



上一篇:js生成随机颜色
下一篇:Nginx location配置详解
该用户未在地球留下任何的痕迹

本版积分规则

QQ|小黑屋|帮助|IT技术擎 ( 沪ICP备15054863号  

GMT+8, 2018-8-22 15:52

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表