promise顺序执行,返回结果存放在数组
遇到面试的一个编程题:三个返回promise对象的异步操作,让你写一个函数可以将这些操作顺序执行,并返回一个数组包含三个异步对象的结果
异步对象:
// 异步函数a
var a = function () {
return new Promise(function (resolve, reject) {
console.log("a")
setTimeout(function () {
resolve('a')
}, )
})
} // 异步函数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')
}, )
})
}
注意: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方法
promise顺序执行,返回结果存放在数组的更多相关文章
- reduce + Promise 顺序执行代码
本文地址: http://www.cnblogs.com/jasonxuli/p/4398742.html 下午的太阳晒得昏昏沉沉,和上周五一样迷糊,看一段代码半天没看明白,刚才不知不觉眯了几分钟,醒 ...
- 超耐心地毯式分析,来试试这道看似简单但暗藏玄机的Promise顺序执行题
壹 ❀ 引 就在昨天,与朋友聊到JS基础时,她突然想起之前在面试时,遇到了一道难以理解的Promise执行顺序题.由于我之前专门写过手写promise的文章,对于部分原理也还算了解,出于兴趣我便要了这 ...
- 8张图让你一步步看清 async/await 和 promise 的执行顺序
摘要: 面试必问 原文:8张图帮你一步步看清 async/await 和 promise 的执行顺序 作者:ziwei3749 Fundebug经授权转载,版权归原作者所有. 为什么写这篇文章? 说实 ...
- ES6 Promise 让异步函数顺序执行
应用 ES6 的 内置对象 Promise, 让异步函数 按顺序执行的例子 如下: 上边 是四个用Promise 处理过的 异步执行的函数: fn1.fn2.fn3.fn4 下面,让其按顺序执行 如下 ...
- Promise 异步函数顺序执行
可以满足需求,且使用方法和Promise.all统一 var a = function() { return new Promise(function(resolve, reject) { setTi ...
- promise实现图片按照指定的加载顺序执行
promise实现图片按照指定的加载顺序执行,先加载第二张,再加载第一张,最后加载第三张 <!DOCTYPE html> <html lang="en"> ...
- js函数整合队列顺序执行插件
前言 在日常开发中,也许我们会遇到这样的一个问题.我们利用[发布订阅模式](如果不了解的可以直接访问此链接www.cnblogs.com/xiaoxiaokun- )去执行[发布]事件时,遇到函数内部 ...
- js多个异步请求,按顺序执行next
在js里面,偶尔会遇见需要多个异步按照顺序执行请求,又不想多层嵌套,,这里和promise.all的区别在于,promise或者Jquery里面的$.when 是同时发送多个请求,一起返回,发出去的顺 ...
- js的并行加载以及顺序执行
重新温习了下这段内容,发现各个浏览器的兼容性真的是搞大了头,处理起来很是麻烦. 现在现总结下并行加载多个js的方法: 1,对于动态createElement('script')的方式,对所有浏览器都是 ...
随机推荐
- scrapy-scrapy如何打开页面?[转]
一.首先我们来看scrapy spider如何打开页面: 要打开页面,我们用的是手,同样scrapy也有一个得力助手:spider:至于spider如何打开页面,且听我娓娓道来,如果一上来就噼里啪啦的 ...
- screen.height && screen.width
screen.height && screen.width how to get window max width in js screen.height; screen.width; ...
- mybatis的mapper参数传递
简单参数传递 简单参数传递是指: 传递单个基本类型参数,数字类型.String 传递多个基本类型参数 parameterType 属性可以省略: 传递单个基本类型参数 SQL语句中参数的引用名称并不 ...
- 当给属性添加final 时候 则无法进行第二次值的修改
- zabbix 自定义监控nginx
zabbix自定义nginx监控项 查看nginx编译安装是否加上该选项,如果没有请重新编译安装 配置nginx.conf vim /usr/local/cpgroup/nginx/conf/vhos ...
- HNOI2018毒瘤
题面链接 luogu sol 这篇博是骗访问量的QwQ. 考虑树怎么做,简单容斥.诸如\(f[u][0]=\prod (f[v][0]+f[v][1]),f[u][1]=\prod f[v][0]\) ...
- loj Snakes 的 Naïve Graph 【数论】
题目链接 loj 题解 感谢珂神的指导orz 观察式子\(i \times j \equiv 1 \pmod m\),显然\(i,j\)是模\(m\)意义下成对的逆元,只需统计模\(m\)意义下存在逆 ...
- 【hdu3555】 Bomb
http://acm.hdu.edu.cn/showproblem.php?pid=3555 (题目链接) 题意 求区间${[1,n]}$含有49的数的个数. Solution 数位dp,先求出不含4 ...
- ActiveMQ反序列化漏洞(CVE-2015-5254)复现
0x00 漏洞前言 Apache ActiveMQ是美国阿帕奇(Apache)软件基金会所研发的一套开源的消息中间件,它支持Java消息服务,集群,Spring Framework等.Apache ...
- 一次lvs迁移记录
需求:从117.119.33.99迁移到122.14.206.125,lvs为dr模式,系统版本为debian7 1.安装lvs和keepalived # aptitude install -y ip ...