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')的方式,对所有浏览器都是 ...
随机推荐
- EasyUseCase 一款脑图转化 Excel 测试用例工具 (1.2 版本升级)
EasyUseCase 本工具由本人自主开发.经过内部实践有效提升测试用例编写效率200% 覆盖率可度量.利用读取xmind软件图表转换符合国人基本需求的测试用例,让手动写Excel用例的日子过去,发 ...
- Android 开发工具下载中文网站
Android官方网站(develop.android.com)因为被墙而无法访问.这时可以访问中文网址: http://wear.techbrood.com/ SDK Manager 代理及安装文件 ...
- SpringBoot(七)_统一异常处理
我感觉看了这节课,给我的思考还是很多的,感觉受益良多.废话不多说,一起学习. 统一的 外层结构返回 这样利于代码看着也规范,前端处理也统一 # 错误返回 { "code": 1, ...
- input accept 属性
*.3gpp audio/3gpp, video/3gpp 3GPP Audio/Video *.ac3 audio/ac3 AC3 Audio *.asf allpication/vnd.ms-as ...
- Kafka日志存储原理
引言 Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的.每个topic又可以分成几个不同的partition(每个topic有几个partition是在创建 ...
- Extend to Palindrome UVA - 11475(补成回文串)
题意: 就是用最少的字符把原字符串补成回文串 解析: emm/.../网上都是用kmp和后缀数组做的 我没想到这俩的思路...emmm... 想到了exkmp的 就是原串和逆串匹配一下 注意要保证 ...
- Ifter Party LightOJ - 1014(水题)
题意:有C个人,给P个食物,每人吃Q个,剩L个.然后给你P和L(Q>L),让你求Q的可能情况,如果有多种可能,从小到大输出:如果不存在,输出impossible 就是求写出公式 遍历c求P-L的 ...
- C++ STL 常用算术和生成算法
C++ STL 常用算术和生成算法 accumulate() accumulate: 对指定范围内的元素求和,然后结果再加上一个由val指定的初始值. #include<numeric> ...
- AJAX实现无刷新登录
最近学习了如何实现无刷新登录,大体的效果如下(界面比较丑,请自行忽略....): 点击登录按钮时弹出登录窗口,输入正确的用户名密码后点击登录则登录窗口关闭,状态改为当前用户名. 第一步: 首先弹出窗口 ...
- 【BZOJ3293】分金币(贪心)
[BZOJ3293]分金币(贪心) 题面 BZOJ 洛谷 题解 和上一题一样啊. #include<cstdio> #include<cmath> #include<al ...