我发现了一些有关jQuery承诺的有趣帖子,我自己也尝试过这个功能。我编写了以下代码,但遇到了一个问题。
var promises = [];
objects.forEach(function(obj) {
promises.push(
$.ajax({
url: 'myurl' + obj.id,
dataType: 'jsonp'
})
)
});
var everything = $.when.apply($,promises).done(function() {..})
到目前为止一切顺利。
之后,我认为我可以使用“一切”来理解整个过程完成后的过程:
$.when(everything).done( function() { business logic })
但最后一行立即被解雇,所以有些东西不能正常工作,我不太明白。你能帮我个忙吗?感谢
答案 0 :(得分:3)
问题是.done()
没有返回新的承诺,它只接受一些处理程序并返回相同的承诺。 jQuery的承诺非常破碎(参见“关于jQuery的Promise实现的注释”)。在几乎所有其他承诺库中,.done
的行为类似于.then
,但返回undefined
并确保错误消息不会被静音。在jQuery中它和巧克力防火手一样有用。
有一个.then
方法充当转换(有点像.map
数组。
考虑到这一点,你可以这样做:
var promises = objects.map(function(obj) {
return $.ajax({
url: 'myurl' + obj.id,
dataType: 'jsonp'
});
});
var everything = $.when.apply($, promises).then(function() {..});
$.when(everything).done( function() { business logic });
同样值得注意的是,因为everything
已经是一个承诺,$.when(everything)
只是一个传递,所以你实际上只能写:
everything.done(function () { business logic })
值得注意的是,jQuery的承诺实现非常糟糕。它并没有遵守绝大多数其他promise实现所使用的Promises/A+规范。 Promises / A +经过深思熟虑,是大量辛勤工作和实验的结果。 jQuery偏离这一特定情况通常会使其更难使用。
如果您要使用替代实施(例如Q或我自己的promise),您可以这样做:
Q($.ajax({
url: 'myurl' + obj.id,
dataType: 'jsonp'
}));
或
var Promise = require('promise');
Promise.from($.ajax({
url: 'myurl' + obj.id,
dataType: 'jsonp'
}));
从jQuery中获得真正的Promises / A +承诺。
答案 1 :(得分:1)
$.when(everything)...
完全合法但不必要,因为$.when()
是一个“承诺组合器”,旨在接受多个承诺参数。
由于everything
已经是由$.when.apply(...).done(...)
链返回的承诺,因此它的名称可能更清晰如下:
var everything_promise = $.when.apply($, promises).then(function() {..});
可以按如下方式调用其他承诺方法:
everything_promise.done(function() {..}).fail(function() {..});
根据具体情况,您也可以选择使用.then()
。
everything_promise.then(function() {..}, function() {..});
关于时间安排,您的原始$.when(everything)...
表单和我的everything_promise.done(...)
表单: