[英]Promise.all resolving earlier than expected
我正在使用Promises编写第一段代码,并且得到了一些意想不到的结果。 我有一些看起来像这样的代码(使用jQuery):
$('.loading-spinner').show();
$('.elements').replaceWith(function() {
// Blocking code to generate and return a replacement element
});
$('.newElements').blockingFunction();
$('.loading-spinner').hide();
为了防止该代码运行时页面被阻塞,我尝试使用setTimeout和Promises使其异步,如下所示:
$('.loading-spinner').show();
var promises = [];
var promises2 = [];
$('.elements').each(function(i, el){
promises[i] = new Promise(function(resolve, reject) {
setTimeout(function() {
$(el).replaceWith(function() {
// Code to generate and return a replacement element
});
resolve(true);
}, 100);
});
});
Promise.all(promises).then(function(values) {
$('.newElements').each(function(i, el) {
promises2[i] = new Promise(function(resolve, reject) {
setTimeout(function() {
$(el).blockingFunction();
resolve(true);
}, 100);
});
});
});
Promise.all(promises2).then(function(values) {
$('.loading-spinner').hide();
});
我正在努力实现的是,一旦在承诺promises
得到解决,在承诺promises2
被实例化。 解决这些问题后,将隐藏加载微调器。
我得到的效果是,尽管页面没有被长时间阻塞,但所有的Promise都设置好之后,微调框就会消失,而不是等它们解决之后再消失。
我可以看到, promises2
Promises不会解决,直到promises
所有事情都解决了,所以我不明白为什么会这样。 我想这可能是由于我不能正确理解Promise,或者是低估了使代码异步。
你打电话Promise.all
上promises2
你填充它之前,其实当你调用它,它包含一个空的阵列,它调用Promise.all
空阵列上,从而立即解决,而无需等待中的承诺promises
。
快速解决:
function delay(ms){ // quick promisified delay function
return new Promise(function(r){ setTimeout(r,ms);});
}
var promises = $('.elements').map(function(i, el){
return delay(100).then(function(){
$(el).replaceWith(function() {
// Code to generate and return a replacement element
});
});
Promises.all(promises).then(function(els){
var ps = $('.newElements').map(function(i, el) {
return delay(100).then(function(){
$(el).blockingFunction();
});
});
return Promise.all(ps);
}).then(function(){
$('.loading-spinner').hide();
});
不过,我们可以做得更好,没有理由为n
元素触发n
超时:
delay(100).then(function(){
$(".elements").each(function(i,el){
$(el).replaceWith(function(){ /* code to generate element */});
});
}).
then(function(){ return delay(100); }).
then(function(){
$('.newElements').each(function(i, el) { $(el).blockingFunction(); });
}).then(function(){
$('.loading-spinner').hide();
}).catch(function(err){
throw err;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.