使用jQuery承诺

时间:2013-07-12 14:40:21

标签: jquery promise

我发现了一些有关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 })

但最后一行立即被解雇,所以有些东西不能正常工作,我不太明白。你能帮我个忙吗?感谢

2 个答案:

答案 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实现的注释

值得注意的是,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(...)表单:

    如果承诺已经解决或被拒绝,
  • 将立即开火
  • 可能会在承诺解决或被拒绝的某个时候触发