我可以异步解决一堆与Promise.all(array)
承诺。但是毕竟这些承诺都得到了解决.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.all
因为承诺返回从Promise.all
等待从提供的阵列中的所有承诺,同时分解(而不是按顺序),它本身解决之前,是无法实现这个顺序。
相反,你可以单独创建的承诺,并同时他们的请求的火:
// create promises and make concurrent requests
const s1 = getStuff(1, 200);
const s2 = getStuff(2, 100);
const s3 = getStuff(3, 250);
// ...
然后,创建关于如何处理它们(stuff2之前stuff1,stuff3之前stuff2等)的反应链
// 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)
}
反应承诺在承诺创建顺序相同的结果,你可以改变你getStuff
功能动态连锁使用Array.prototype.reduce
的反应:
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)
});
nem035的答案是当场上。我想指出的是,通常在这种情况下要采取的请求时,发生同样的动作和另一个动作时,他们就大功告成了。
您可以使用.all
为与.map
:
Promise.all([ getStuff(1, 200),
getStuff(2, 100),
getStuff(3, 250),
getStuff(4, 200),
getStuff(5, 300),
getStuff(6, 250),
getStuff(7, 5000)]
.map(request => request.then(v => {
console.log("Request done! Got," v); // or some action per request
return v;
})).then(data => console.log(data));
您可老板的进一步.map
使用您正在使用的每个请求的相同功能的事实:
Promise.all([[1, 200],
[2, 100],
[3, 250],
[4, 200],
[5, 300],
[6, 250],
[7, 5000]])
.map((a, b) => getStuff(a, b))
.map(request => request.then(v => {
console.log("Request done! Got," v); // or some action per request
return v;
})).then(data => console.log(data));
并进一步:
Promise.all([200, 100, 250, 200, 300, 250, 5000])
.map((a, i) => getStuff(a, i + 1))
.map(request => request.then(v => {
console.log("Request done! Got," v); // or some action per request
return v;
})).then(data => console.log(data));
或与蓝鸟:
const sideEffect = v => console.log("Got partial result", v));
const data = [200, 100, 250, 200, 300, 250, 5000];
Promise.map(data, (a, i) => getStuff(a, i + 1).tap(sideEffect))
.then(data => console.log(data));
当然 - 你应该只是解决您的后端,这是完全不合理的要求客户,以便为数据的不同部分7度的要求 - 有后台拿范围。
我知道这不是本地人,但与蓝鸟你可以使用Promise.some
(以fullfill count
承诺已履行后)或Promise.mapSeries
(串联fullfill承诺)以某种方式达到你所期望的流量。
正常运行:您可以放心地使用Promise.all()
。该承诺executers将同时被解雇,结果将在你插入你的承诺到承诺阵列的顺序返回。然后就看你对它们进行排序,你喜欢的方式。如下面的代码片段,我们有五个承诺将每5秒钟内随机解决。不管它们的解决时间,你将得到的结果最新做出决议时;
var promises = [ new Promise( v => setTimeout(_ => v("1st paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("2nd paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("3rd paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("4th paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("5th paragraph text"),~~(Math.random()*5000))),
];
Promise.all(promises)
.then(result => console.log(result.reduce((p,c) => p + "\n" + c)));
你想要什么:但你不希望只要等待的最后一个结束,而是要处理他们的顺序,他们尽快得到解决。然后Array.prototype.reduce()
是你最好的朋友在这里。如
var promises = [ new Promise( v => setTimeout(_ => v("1st paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("2nd paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("3rd paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("4th paragraph text"),~~(Math.random()*5000))),
new Promise( v => setTimeout(_ => v("5th paragraph text"),~~(Math.random()*5000)))
];
promises.reduce((p,c) => p.then(result => (console.log(result + "\n"),c)))
.then(result => (console.log(result + "\n")));
请运行该代码多次看到代码的行为。该文本将尽快更新的承诺做出决议,但只有当它是轮到。所以,如果一日2次后消失,我们将看到第1次和第2次出现在他们的订单一次,但他们不会等待3到等解析...