添加.done()回调到自定义函数

时间:2014-03-17 12:27:08

标签: javascript jquery ajax promise

我将这些功能包含在一个小类中:

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()函数。

我该怎么办?

2 个答案:

答案 0 :(得分:4)

done是promise API的一部分。

Promise是流控制的抽象,允许您以“更同步”的方式编写异步代码。

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
});

承诺实现,至少其中一些,包括.done方法,类似于.then,区别在于它将错误记录到控制台,而不是允许您在承诺链中处理它们(承诺可以做的另一件令人敬畏的事情。)

您可以简单地在您的案例中返回承诺:

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。

值得一提的是,那里有更好,更快,更有能力的承诺。

答案 1 :(得分:2)

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

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

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