我发布了similar question related to Ember.RSVP.all
,但我发现其行为与Promise.all
行为相同。如果我违反任何规则,请通过单独提交来告诉我。
我正在尝试在承诺链中使用Promise.all。我的例子比我的使用简单得多,但它证明了这个问题。在一系列承诺的中间,我有一套承诺,在链条可以继续之前都需要解决 - 正是我所理解的Promise.all是为了。
不幸的是,当我返回Promise.all对象时,链中的下一个promise立即运行,而不等待传递给all()的promise。
我已经设置了一个js小提琴,用我能想到的最佳方式进行演示:
请注意,First和Second都在几乎完全相同的时间解决,当Second应该在1s promise之后。第三和第四按预期进行。
小提琴代码如下所示:
function delayAjax(delay) {
return $.ajax({
url: '/echo/json/',
data: {
json: '',
delay: delay,
}
});
}
delayAjax(1).then(function() {
$('#first').addClass('red');
var proms = [delayAjax(1), delayAjax(1)];
return Promise.all(proms).then(function() {
$('#onepointfive').addClass('red');
});
}).then(function() {
$('#second').addClass('red');
return delayAjax(1);
}).then(function() {
$('#third').addClass('red');
return delayAjax(1);
}).then(function() {
$('#fourth').addClass('red');
});
HTML
<div id="first">First</div>
<div id="onepointfive">One point five</div>
<div id="second">Second</div>
<div id="third">Third</div>
<div id="fourth">Fourth</div>
答案 0 :(得分:2)
你需要先将jQuery延迟转换为承诺。
function delayAjax(delay) {
return Promise.resolve($.ajax({
url: '/echo/json/',
data: {
json: '',
delay: delay,
}
}));
}
答案 1 :(得分:0)
You Don't Know JS: Async & Performance中有一节讨论如何管理不可信赖的问题:Trustable Promise?。
确实以Promise.resolve(thenable)
作为解决此问题的方法。
我不太了解您为什么会目睹您的行为,但Domenic Denicola的文章You're Missing the Point of Promises介绍了为什么jQuery的延迟不是真正的承诺,以及为什么它们有问题。在文章的最后,他提供了处理Q库中不可信任的承诺的方法,即使用Q.when()
(Angularjs $q
服务也为此提供.when()
方法目的):
return Q.when($.ajax({
url: '/echo/json/',
data: {
json: '',
delay: delay,
}
}));