【问题标题】:Chaining ajax deferreds between function calls在函数调用之间链接 ajax 延迟
【发布时间】:2012-06-12 21:47:53
【问题描述】:

我在使用 jQuery Deferred 时遇到了一些问题。

我在函数包装器中使用 jQuery ajax 调用,并且尝试按照范围顺序依次链接两个成功回调。但是,两个成功回调同时执行,这会导致问题。

我的初始函数调用如下所示(system.log 是更智能的 console.log。):

serverpaths.setConfig(path).then(system.log("BAM! SERVERPATHS: " + serverpaths));

在这个 setConfig 方法中,我有一个 AJAX 调用,其中链接了一个 .then()。 (system.defer 是一个包装器,它返回一个 jQuery.Deferred 对象;http.get 是一个 jQuery.ajax 的包装器。)

config.setConfig = function (configObj) {
    var that = this;
    var inlineHelper = function (data) {
        return system.defer(function (dfd) {
            for (var key in data) {
                system.log("Config[" + key + "]: " + that[key]);
                system.log("Data[" + key + "]: " + data[key]);
                that[key] = data[key];
                system.log("New Config[" + key + "]: " + that[key]);
            }
        }).promise();
    };

    if (typeof configObj === "string") {
        http.get("api/getPathConfig")             // The problem seems to be in this area
            .then(function (data) {
                return system.defer(function () {
                    inlineHelper(data);
                }).promise();
            });
    } else {
        return system.defer(function () {
            inlineHelper(configObj);
        }).promise();
    }
};

理想情况下,应该调用 ajax 请求,然后调用 inlinehelper,然后调用 system.log,因为我正在使用 return 语句将我的 promise 对象踢回链。这里的问题是调用ajax请求,然后同时调用system.log和inlinehelper。

以前有没有人遇到过这样的问题?函数作用域和异步调用似乎在这里互相争斗。我确信我可以解决这个问题,但这似乎不太合乎逻辑——我的猜测是,当我的 ajax 请求成功触发时,它会在我的主范围内触发 .then() 调用,而我并不想要它。我确信我可以解决这个问题,但是拥有一个优秀的开发者社区来激发想法会有所帮助。

感谢您的所有建议。谢谢!

【问题讨论】:

  • 您感谢我的建议吗? :)

标签: jquery jquery-deferred


【解决方案1】:

.then(function() { return promise }) 什么都不做。您返回的承诺不会传播到下一个延迟回调。

如果您想这样做,请使用.pipe() 而不是.then()。这样你就可以链接承诺。

如果你想链接 3 个异步调用,这样做:

firstDeferredCall.pipe(secondDeferredCall).pipe(thirdDeferredCall)

如果你写

firstDeferredCall.then(secondDeferredCall).then(thirdDeferredCall)

thirdDeferredCall 不会等待secondDeferredCall 调用被执行。

编辑:正如蒂姆所说,.pipedeprecated since jQuery 1.8

如果您使用的是 jQuery 1.8+,您可以使用 .then,它现在替换了 .pipeSee documentation for .then。在这种情况下,您的代码应该是好的,无需任何修改。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多