【问题标题】:Add .done() callback to custom function将 .done() 回调添加到自定义函数
【发布时间】:2014-03-17 20:49:41
【问题描述】:

我将这些函数包含在一个小类中:

var Ajax = {
  // Send new entry data to database
  endNewEntry: function (json) {
    $.post("/controllers/insertEntry.ajax.php", {"json": json});
  },
  loadView: function (view, target, extra) {
    var input = $.extend({}, {"view": "../" + view}, extra) || {"view": "../" + view};

    $.get("/controllers/loadView.ajax.php", input, function (data) {
      $(target).replaceWith(data);
    });
  }
};

如您所见,这两个函数都使用 jQuery $.ajax 向我的服务器执行请求并将我的部分文档替换为响应。

现在我想为这些函数添加一个功能,让我在发布请求完成时调用另一个函数(回调)。

我想要这样的语法:

Ajax.loadView(view, target, extra).done( function() { something; });

相反,我知道的唯一方法是将另一个参数添加到定义我的回调函数的loadView,但我想要.done() 函数。

我该怎么办?

【问题讨论】:

    标签: javascript jquery ajax promise


    【解决方案1】:

    done 是 Promise API 的一部分。

    Promises 是对流控制的抽象,让您可以以“更同步”的方式编写异步代码。

    promise 对象有一个.then 方法,允许您将操作链接到它,并且保证每个操作仅在前一个操作完成时终止。

    myAjax().then(function(result){
        // do something with result, myAjax done here
        return otherAjax();
    }).then(function(otherResult){
        // otherAjax done here, this only gets called after the above code handling myAjax is done
    });
    

    Promise 实现,至少其中一些,包括一个类似于 .then.done 方法,不同之处在于它将错误记录到控制台,而不是允许您在 Promise 链中处理它们(另一个很棒的事情 Promise可以)。

    您可以简单地在您的情况下返回承诺:

    var Ajax = {
      // Send new entry data to database
      endNewEntry: function (json) {
        return $.post("/controllers/insertEntry.ajax.php", {"json": json});
      },
      loadView: function (view, target, extra) {
        var input = $.extend({}, {"view": "../" + view}, extra) || {"view": "../" + view};
    
        return $.get("/controllers/loadView.ajax.php", input, function (data) {
          $(target).replaceWith(data);
        });
      }
    };
    

    这会让你做什么:

    Ajax.loadView().done(function(data){
        //do something with the result, in variable data here.
    });
    

    您当然可以像上图所示将事物链接到它,以便执行多个异步操作。 jQuery 还提供了$.when 用于等待多个承诺。

    值得一提的是,现在有更好、更快、更有能力的 Promise 实现。

    【讨论】:

    • 谢谢!我不知道 jQuery 内置了对 Promise 的支持。它完美无缺。
    【解决方案2】:

    由于$.get 返回promise(假设您使用的是 jQuery >= 1.7),只需返回即可访问所需的属性:

    return $.get("/controllers/loadView.ajax.php", input, function (data) {
      $(target).replaceWith(data);
    });
    

    我也会在done() 回调中亲自处理$(target).replaceWith(data);,以避免混淆。

    【讨论】:

    • +1 建议将 .replaceWith 放在 .done 中,就我个人而言,我会把它放在 .then 中,但也许那是因为我习惯了像 Bluebird 这样的不那么破坏承诺的实现.
    • 我可以将replaceWith() 移动到done()then() 但这样我就有一个loadView() 函数不会加载任何东西,我应该重复很​​多每次我需要加载视图时,都会对 replaceWith() 函数进行多次。
    • @BenjaminGruenbaum 这实际上是我的错字。我完全同意。
    猜你喜欢
    • 2023-03-30
    • 2010-10-31
    • 2021-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多