Добавить.done() обратный вызов для пользовательской функции

Я включил эти функции в небольшой класс:

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 ответа

Решение

done является частью обещания API.

Обещания - это абстракция управления потоком, которая позволяет писать асинхронный код "более синхронно".

Объект обещания имеет .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 за ожидание нескольких обещаний.

Стоит отметить, что есть намного лучшие, более быстрые и более способные реализации обещаний.

Поскольку $.get возвращает promise (при условии, что вы используете jQuery >= 1.7), просто вернитесь и получите доступ к нужным вам свойствам:

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

И я бы лично справился $(target).replaceWith(data); в done() Обратный звонок также, чтобы избежать путаницы.

Другие вопросы по тегам