令人惊讶的.ajax()承诺在jQuery中承诺

时间:2015-02-14 07:43:57

标签: jquery

按如下方式链接两个$ .ajax()调用:

[EXAMPLE 1]
var promise1 = $.ajax({url: remoteUrl, type: 'POST'});
promise1.then(
    function() {
        $.ajax({url: remoteUrl});
    }
);

按预期在远程服务器上生成以下事件:

ENTER api_ping() ...
.
.
.
leave api_ping() ...
ENTER api_ping() ...
.
.
.
leave api_ping() ...

但是,使用以下更简单的语法:

[EXAMPLE 2]
var promise1 = $.ajax({url: remoteUrl, type: 'POST'});
promise1.then(
    $.ajax({url: remoteUrl})
);

序列失去了:

ENTER api_ping() ...
.
ENTER api_ping() ...
.
.
.
leave api_ping() ...
leave api_ping() ...

令我惊讶的是,因为.then()是可链接的并且会返回一个新的承诺。

我们可以得出结论,如果.then()没有传递一个函数,而是一个承诺, 然后新承诺将与原始承诺具有相同的行为,这是一个遗憾 因为当您需要链接一长串调用时,第二种语法非常优越 按顺序。

然而,更奇怪的事情发生了。 如果您使用GET而不是POST,如下所示:

[EXAMPLE 3]
var promise1 = $.ajax({url: remoteUrl, type: 'GET'});
promise1.then(
    $.ajax({url: remoteUrl})
);

恢复原来的“正确”行为:

ENTER api_ping() ...
.
.
.
leave api_ping() ...
ENTER api_ping() ...
.
.
.
leave api_ping() ...

我正试图找出一个合理的解释......建议?

2 个答案:

答案 0 :(得分:1)

这是因为Javascript语法和评估规则。在第二个示例中,调用$.ajax({url: remoteUrl})并将其返回值传递给promise1.then()

$.ajax()返回时,它已经发送了请求。

至于服务器上的事件发生时间,在这种情况下,似乎服务器处理GET请求的速度稍快一点,以便它们在服务器上顺序运行(服务器完成)在开始处理敲门的下一个GET请求之前做出响应)。这仅仅是偶然的;如果有足够的重试次数,你也可以同时运行。

对于后一种模式,是的,有可能有一个像$.ajax这样的函数返回一个在调用then时调用的延迟函数,但为什么呢? "模式"你正在使用的根本不是一个模式,真正的程序需要以繁忙的循环方式触发常量的AJAX请求。

答案 1 :(得分:1)

你正在第二个例子中立即执行该功能。

在第3个示例中,浏览器(或服务器)必须将GET请求序列化到同一个uri,以便它可以重用缓存(如果可能)或其他浏览器/服务器行为。

如果你想保持清晰我认为你可以这样做:

var someUpdate1 = function() {
    return $.ajax({url: remoteUrl});
}
var someUpdate2 = function() {
    return $.ajax({url: remoteUrl});
}

var updates = someUpdate1
              .then(someUpdate2)
              .then(...);