【问题标题】:Chaining $.ajax() for synchronous requests with Q doesn't work使用 Q 链接同步请求的 $.ajax() 不起作用
【发布时间】:2017-02-21 07:46:54
【问题描述】:

我需要获取资源 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;   

【问题讨论】:

  • 你为什么要用 Q 和 jQuery $.ajax,只要你在做 asynchronous 请求就没有必要了。
  • 检查这个答案,这可能会帮助你stackoverflow.com/a/39679275/6608101
  • @adeneo 不能将 async 设置为 false,因为这会从不同的来源加载,正在加载.. 让我看看。
  • 你应该NEVER将async设置为false,它应该总是true,这是默认值,即异步请求。
  • 是的,有人建议我不要这样做并研究承诺,因此图书馆 Q,但我似乎无法让它等待另一个完成。

标签: jquery ajax promise q


【解决方案1】:

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

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

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() 调用都立即执行,只有链接的承诺。

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


附:我认为您的问题中缺少一些代码,因为您可能不想每次都执行完全相同的 Ajax 调用。

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

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

【讨论】:

  • 对于缺少的代码,您可能还想指出一个可能的missing closure :-)
  • @Bergi - 添加了这方面的一些信息。
  • 是的,缺少一些更改数据的代码,用函数将其括起来使其工作。谢谢:)
猜你喜欢
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-23
  • 1970-01-01
  • 2015-12-21
  • 2012-11-28
  • 2014-12-28
相关资源
最近更新 更多