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')的方式,对所有浏览器都是 ...
随机推荐
- Android bp语法介绍
参考网址: http://note.qidong.name/demo/soong_build/ 谷歌官网文档: https://android.googlesource.com/platform/bu ...
- IE下Userdata本地化存储
这两天看了下Discuz x2发帖的实时保存机制,涉及到本地化存储,所以上网查了下,Firefox等支持HTML5的浏览器使用window.localStorage或window.sessionSto ...
- MySQL中varchar最大长度是多少
一. varchar存储规则: 4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) 5.0版本以上,varchar(20),指的是20字符,无 ...
- Qss 样式表的尝试
QLineEdit{ border:1px solid #137eb6; padding:2px; background-color:#F5F5F5; } QToolTip{ border:1px s ...
- 随机场(Random field)
一.随机场定义 http://zh.wikipedia.org/zh-cn/随机场 随机场(Random field)定义如下: 在概率论中, 由样本空间Ω = {0, 1, …, G − 1}n取样 ...
- 洛谷P4902乘积
题面链接 洛谷 题意简述 求\(\prod_{i=A}^B\prod_{j=1}^i \lgroup \frac{i}{j} \rgroup ^{\lfloor \frac{i}{j} \rfloor ...
- Group Anagrams - LeetCode
目录 题目链接 注意点 解法 小结 题目链接 Group Anagrams - LeetCode 注意点 字母都是小写的 解法 解法一:用一个字符串表示strs[i]中出现的字母,比如:abc-> ...
- 使用mshta.exe绕过应用程序白名单(多种方法)
0x00 简介 很长一段时间以来,HTA文件一直被web攻击或在野恶意软件下载程序用作恶意程序的一部分.HTA文件在网络安全领域内广为人知,从红队和蓝队的角度来看,它是绕过应用程序白名单有价值的“ ...
- js中相等、大小 不同类型之间是如何进行对比的。
上个小问题 [] > [] false [] < [] false [] == [] false // why? 再上个加强版 '6xxx' < '5xx' false '6xxx' ...
- 解题:USACO07FEB The Cow Lexicon
题面 第一次做Trie上dp,感谢 @i207M 的资瓷 对子串们建立一棵Trie,设$dp[i][j]$表示到母串第$i$位为止在$Trie$上的$j$号节点时的最小修改数量,然后就可以枚举母串各位 ...