【问题标题】:jQuery Deferred not executing asynchronously with getJSON calljQuery Deferred 不与 getJSON 调用异步执行
【发布时间】:2016-09-02 13:12:21
【问题描述】:

我的问题是 b() 最后执行,但它应该是第二个。我想在每次点击按钮时调用一个 JSON api(并且总是发送新的 api 调用),但它应该从 div 中删除最后一个 api 消息:

$(document).ready(function() {

  function test() {

    function a() {
      $("#message-quote, #message-person").empty();
      console.log('p1');
    };

    function b() {
      console.log('p2 - before getJSON');
      $.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
        $("#message-quote").append(a[0].content)
        $("#message-person").append("<p>— " + a[0].title + "</p>")
        console.log('p2 - in getJSON');
      });
    };

    function c() {
      $("body, .button, .quote-icons a").css("background-color", "red");
      $(".quote-text").css("color", "red");
      console.log('p3');
    };

    var d = $.Deferred(),
    p = d.promise();
    p.then(a()).then(b()).then(c());
    d.resolve();
  };

  $("#getMessage").on("click", function() {
    test();
  });

});

我得到的顺序是:

"p1"
"p2 - before getJSON"
"p3"
"p2 - in getJSON"

【问题讨论】:

  • 确定 b() 是最后运行的吗?您是基于控制台输出的断言吗?因为 a()-b()-c() 给你输出 p1-p3-p2。如果您删除承诺并调用a();b();c(),您将得到“p1 p3 p2”。通过在$.getJSON之前添加console.log来确认这一点。
  • 我更新了我的问题。
  • b()添加回车,即:return $.getJSON(...
  • 问题:你明白为什么它是这样排列的吗?你正试图让它与.then()一起工作?

标签: javascript jquery


【解决方案1】:

您不等待 b() 的返回,由于它是异步调用的,因此您需要链接承诺。

如果你从 b() 返回一个 Promise,它应该等待 getJSON 的结果返回后再继续。

另外,您的函数正在立即执行,.then(callback) 需要获取一个稍后可以执行的函数,而您可以直接执行一个函数

function b() {

      return $.getJSON("http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&callback=", function(a) {
        $("#message-quote").append(a[0].content)
        $("#message-person").append("<p>— " + a[0].title + "</p>")
        console.log('p2');
        // resolve the promise, the call has been completed
      });
    };

 var d = $.Deferred(),
    p = d.promise();
    p.then(a)
     .then(b)
     //the context of .then will now be the promise out of b()
     .then(c);
    d.resolve();

注意:Promise 也需要从其他方法返回。

编辑:正如 Rocket 所指出的,jQuery Ajax 调用实现了 promise 方法

工作示例:https://jsfiddle.net/rsfxpg38/4/

你可以从这篇文章中看到一个例子: How do I chain a sequence of deferred functions in jQuery 1.8.x?

【讨论】:

  • 我把你的代码放在函数b()中,但是执行顺序和以前一样。
  • 我有一个关于 jsFiddle 的工作示例,我已经纠正了我的错误
  • jsfiddle控制台中的执行顺序是:ifac initialized! - p1show - p2 - before getJSON - p3show - p2p2应该在p2 - before getJSON之前
  • 您是否为我显示的示例清除了缓存?我现在包含了 10 秒的延迟,我得到了你需要的结果 jsfiddle.net/rsfxpg38/3
  • 您不需要在b() 中使用$.Deferred。你可以return $.getJSON(...);。所有的 AJAX 方法都实现了 promise 方法(在 jQuery 中)。
猜你喜欢
  • 2013-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
相关资源
最近更新 更多