【问题标题】:Using Q,js for ajax calls使用 Q,js 进行 ajax 调用
【发布时间】:2015-09-17 12:00:13
【问题描述】:

我有一个可能需要一些时间才能完成的 ajax 调用。我不想使用async:false,因为我希望它保持非阻塞代码。所以我决定使用 Q。问题是我不明白如何提取从 Q.when($.ajax...) 返回的 json。我是 Q 新手。

在本例中,我希望变量保存从服务器返回的 json:

    var res = Q.when($.ajax({
    type: "POST",
    url: "GetData.asmx/GetMembersList",
    contentType: "application/json; charset=utf-8",
    dataType: "json"
    }));

return res;

【问题讨论】:

  • Promise 不会让你的代码同步。 res 仍然是一个承诺。

标签: javascript jquery promise


【解决方案1】:

使用异步调用,您不能只将结果分配给变量,因为该结果要到将来某个时候才会存在。 Q.when 不返回结果,它返回一个 promise 对象,该对象最终会得到一个结果。

如果您只想对 JSON 做一件事,您只需内联 .then 调用即可获得结果。

Q($.ajax({
  type: "POST",
  url: "GetData.asmx/GetMembersList",
  contentType: "application/json; charset=utf-8",
  dataType: "json"
})).then(function (res) {
  // res now contains the JSON
});

然而,Promise 的真正威力在于您可以传递它们并在以后使用它们。

function getMembersList() {
  return Q($.ajax({
    type: "POST",
    url: "GetData.asmx/GetMembersList",
    contentType: "application/json; charset=utf-8",
    dataType: "json"
  }));
}

var membersList = getMembersList();

membersList.then(function (res) {
  // once the AJAX call completes this will
  // run. Inside this function res contains the JSON
  return res; // pass res to the next chained .then()
}).then(function (res) {
  // you could chain another then handler here
});

// do some other stuff

membersList.then(function (res) {
  // you could also add another then handler later too
  // even long after the AJAX request resolved and this
  // will be called immediately since the promise has already
  // resolved and receive the JSON just like the other
  // then handlers.
});

如果您没有其他原因使用 Q,则不需要使用 Q,因为 1.5 版 jQuery 从 AJAX 调用返回 deferred object。 Deferred 类似于 Promise。 Q 确实 offer more power 和 jQuery 的 promises/deferreds 并没有完全实现 Promises/A 标准,可能会导致错误处理问题。对于像 AJAX 调用这样简单的事情,如果您已经在使用 jQuery,那么 jQuery 承诺通常就足够了。

var membersList = $.ajax({
  type: "POST",
  url: "GetData.asmx/GetMembersList",
  contentType: "application/json; charset=utf-8",
  dataType: "json"
});

membersList.then(function (res) {
  // res now contains the JSON
});

【讨论】:

  • 完美解释!我终于明白它是如何工作的了。
  • 只是想知道我做对了,所以在 memberlist 代码中,调用 getMemberList ajax 调用,然后脚本执行第一个“then”,然后执行“do some other things " 然后它执行第二个 "then"?或者当你进行 ajax 调用时,它会执行 ajax,然后是第一个“then”,然后是第二个“then”,跳过“做一些其他事情”代码?
  • 事物按源顺序执行。 then 会立即执行,但是由于 AJAX 调用是异步的,所以 .then() 调用中的匿名函数 callbacks 直到 AJAX 请求解决后才会执行。因此,实际发生的是“在此处执行其他操作”代码将在遇到时立即执行,然后在 AJAX 请求解决后的某个时间后,then 回调将执行。 This fiddle 应该会更清楚。
【解决方案2】:

以下是 q 文档中关于使用 jQuery ajax 的一些示例。

return Q(jQuery.ajax({
    url: "foobar.html", 
    type: "GET"
})).then(function (data) {
    // on success
}, function (xhr) {
    // on failure
});

// Similar to jQuery's "complete" callback: return "xhr" regardless of success or failure
return Q.promise(function (resolve) {
    jQuery.ajax({
        url: "foobar.html",
        type: "GET"
    }).then(function (data, textStatus, jqXHR) {
        delete jqXHR.then; // treat xhr as a non-promise
        resolve(jqXHR);
    }, function (jqXHR, textStatus, errorThrown) {
        delete jqXHR.then; // treat xhr as a non-promise
        resolve(jqXHR);
    });
});

https://github.com/kriskowal/q/wiki/Coming-from-jQuery

希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-09
    • 2012-03-22
    • 1970-01-01
    • 2016-05-04
    • 1970-01-01
    • 2017-02-09
    • 2015-07-22
    • 2016-09-28
    相关资源
    最近更新 更多