使用Q链接同步请求的$ .ajax()不起作用

时间:2016-10-12 13:22:39

标签: jquery ajax promise q

我需要获得资源A,然后是B等,直到n。我按照以下方式按照官方指南https://github.com/kriskowal/q#sequences进行了此操作。

var chain = Q();
            for(var i=0;i<x.length;i++){
            chain = chain.then( $.ajax({
                        type: "POST",
                        url : data_url,
                        data:pdata
                }) );
return chain;   

1 个答案:

答案 0 :(得分:1)

.then()处理程序接受函数引用作为参数,而不是promise。您的代码立即执行了ajax调用,然后将返回的promise传递给无效的.then()处理程序。

如果您希望稍后按顺序执行Ajax调用,则需要将它们放在这样的函数中,以便将该函数引用传递给.then()。通过这种方式,承诺基础架构可以在将来的某个时间调用您的函数:

var chain = Q();
for (var i = 0; i < x.length; i++) {
    chain = chain.then(function(priorResults) {
        return $.ajax({
            type: "POST",
            url: data_url,
            data: pdata
        });
    });
}
return chain;

您将函数引用传递给.then()处理程序,以便promise基础结构可以在以后执行该函数。

如上所述,$.ajax()调用都是立即执行的,只有链接的承诺。

如果您尝试在i处理程序中使用.then()变量,那将无法正常运行,因为for循环已完成且i将具有调用.then()处理程序时的终值。通常的解决方案是在ES6中使用let作为for循环变量,使用.forEach()之类的迭代进行迭代,或者确保for循环包含一个函数/闭包可以唯一地捕获i变量的每个单独值。如果您展示了实际代码,可能会提供更多详细信息。

P.S。我认为你的问题中有一些缺失的代码,因为你可能不想每次都执行完全相同的Ajax调用。

如果您正在迭代一个数组,那么使用promises串行迭代数组的常见设计模式是.reduce(),如下所示:

array.reduce(function(p, item) {
    return p.then(function(priorResult) {
        return $.ajax(...);
    });
}, Q()).then(function(result) {
    // everything done here, final result
});