我可以使用Promise.all(array)
异步解析一堆promises。然而,只有在所有这些承诺都得到解决之后,.then()
才会运行。当承诺得到解决时,我如何执行操作?
例如,我希望使用Promise.all()
异步加载一篇文章中的所有段落-这样,网络请求就可以一次触发。如果段落1加载完成,我希望它呈现到页面上-但只有在段落2之前完成加载时,我才希望加载段落2。如果段落3已经加载完成,而2没有加载,我希望3在渲染到页面之前等待2。诸若此类。
我试过这样的东西,但我不知道下一步该做什么:
var getStuff = function(number, time){
return new Promise(function(resolve, reject){
window.setTimeout(function(){resolve(`${number} - Done.`)}, time);
});
};
Promise.all([ getStuff(1, 200),
getStuff(2, 100),
getStuff(3, 250),
getStuff(4, 200),
getStuff(5, 300),
getStuff(6, 250),
getStuff(7, 5000)])
.then(function(data){
console.log(data);
});
我如何才能获得一个接一个数据的控制台日志-而不是在发出下一个请求之前使用then()
解析每个promise?有没有更好的方法来做这件事?
发布于 2016-09-27 23:43:45
您不能使用Promise.all
实现此顺序,因为从Promise.all
返回的promise会等待所提供的数组中的所有promise并行解析(而不是顺序解析),然后才会自动解析。
相反,您可以同时单独创建其请求的promises和fire:
// create promises and make concurrent requests
const s1 = getStuff(1, 200);
const s2 = getStuff(2, 100);
const s3 = getStuff(3, 250);
// ...
然后创建一个关于如何处理它们的反应链(stuff1先于stuff2,stuff2先于stuff3,等等)
// create a chain of reaction order to the results of parallel promises
s1
.then(console.log) // s1 resolved: log result
.then(() => s2) // chain s2
.then(console.log) // s2 resolved: log result
.then(() => s3) // chain s3
// ...
.then(() => { // chain another function at at the end for when all promises resolved
// all promises resolved (all data was logged)
}
要以创建promise的相同顺序对promise结果做出反应,可以使用Array.prototype.reduce
更改getStuff
函数以动态地链接这些反应
var times = [200, 100, 250, 200, 300, 250, 5000];
var getStuff = function(time, index) { // swap the order of arguments so number is the index passed in from Array.map
return new Promise((resolve, reject) => {
window.setTimeout(() => {
resolve(`${index + 1} - Done.`); // use index + 1 because indexes start at 0
}, time);
});
};
times
// map each time to a promise (and number to the index of that time + 1) and fire of a request
.map(getStuff)
// dynamically build a reaction chain for the results of promises
.reduce((chain, promise) => {
return chain
.then(() => promise)
.then(console.log);
}, Promise.resolve())
.then(() => {
// all promises resolved (all data was logged in order)
});
发布于 2016-09-27 23:44:20
我知道它不是原生的,但使用bluebird,您可以使用Promise.some
(在count
承诺完成后完成)或Promise.mapSeries
(连续完成承诺)以某种方式实现您期望的流程。
https://stackoverflow.com/questions/39728793
复制相似问题