Promises称他们的成功回调为时已晚

时间:2014-06-26 09:58:26

标签: javascript jquery ajax promise

我的代码如下:

products.SaveApplications = function (product) {
    var promises = [];

    ko.utils.arrayForEach(product.Applications(), function (item) {
       var applicationToSend = ko.mapping.toJS(item);
       promises.push($.ajax({
             type: "POST",
             contentType: "application/json",
             url: serviceUrl + "/InsertApplication",
             data: JSON.stringify(applicationToSend),
             success: function (data) {
                 alert("Doing success callback now.");
                 item.ID(data);
             }}));
    });

    return promises;
}

然后一个函数products.SaveEnvironments,它基本上是相同的,除了它在我的控制器中调用一个不同的函数,和一个函数products.SaveInstallations,它再次大部分是相同的,除了它需要等待环境和应用程序保存,因为它有一些依赖数据(Application.ID和Environment.ID)。

现在我有一个函数,它调用这两个函数并等待它们直到完成:

products.SaveChanges = function (product) {
    // (...)
    var promises = products.SaveApplications(product);
    promises = promises.concat(products.SaveEnvironments(product));

    $.when(promises).done(function () {
       alert("we shouldn't see this before the other message!");
       products.SaveInstallations(product);
    }); 
};

问题是警告框中有“我们不应该在另一条消息之前看到此消息!”实际上出现在“立即成功回调”之前,这意味着我的ID属性当时为空。它让我得出结论:$.when调用仅执行实际的承诺,但不等待成功回调完成。我怎么能让它等待?谢谢。

1 个答案:

答案 0 :(得分:1)

您错误地使用了$.when。你不能将多个promise作为数组传递给它;如果你这样做,它会像任何其他非承诺值一样处理数组,并将其转换为一个完整的promise,其中包含仍在等待的promise的数组作为结果。那当然没用。

您需要使用.apply来模拟调用$.when,将每个promise作为单独的参数,如下所示:

$.when.apply(null, promises).done(function () { ... });