JQuery Promises и Backbone

Я нашел этот фрагмент кода, который делает то, что я хочу:

var promise = this.model.save();
$.when(promise).then(function() {
 console.log(promise.responseText);
});

Я хочу вернуть responseText из моего вызова Backbone в this.model.save(). Этот код был задокументирован здесь. Но он ничего не записывает, даже если я вытащил необработанную текстовую строку в вызов console.log().

Может ли кто-нибудь объяснить в непрофессионалах, что такое обещание jQuery? Я читал о них, но я не думаю, что у меня все получилось. Это может помочь мне понять, почему этот код не работает для меня. Если я console.log(promise) находится между первой и второй строками кода, я получаю responseText. Итак, что-то происходит либо в $.when, либо в then, что приводит к ошибке.

ИЗМЕНИТЬ:

Прочитав статью, я обнаружил, что могу это сделать:

var promise = this.model.save(); 
$.when(promise).then(null, function(obj) {
 console.log(obj.responseText);
});

Но я не понимаю, что представляет null. then, кажется, принимает два параметра, функцию успеха и функцию сбоя. Но разве функция успеха не была бы первой? Я получаю 200 ответов от сервера.

3 ответа

Итак, во-первых, я уверен, что вам не нужна часть when; из документов jQuery:

Объекты jqXHR, возвращаемые $.ajax() из jQuery 1.5, реализуют Интерфейс Promise, предоставляющий им все свойства, методы и поведение Promise (см. раздел "Отложенный объект" для получения дополнительной информации).

Так как Promise уже имеет метод then, вы можете просто сделать:

this.model.save().then(null, function(obj) {
 console.log(obj.responseText);
});

(Тот факт, что приведенный выше код почти читается как английское предложение, является основным преимуществом использования Отсрочки, по крайней мере для меня.)

Что касается вашего аргумента null, документы снова довольно понятны. Есть три подписи для then (и это просто для того, чтобы покрыть разные версии jQuery, любая версия имеет меньше):

deferred.then(doneFilter [, failFilter] [, progressFilter])

deferred.then(doneCallbacks, failCallbacks)

deferred.then(doneCallbacks, failCallbacks [, progressCallbacks])

Как вы можете видеть, все три сначала выполняют "сделанную" функцию, а функцию отказа - вторую. Это, по-видимому, означает, что вы получаете сбой, что путает. Один из способов избежать проблемы - вообще не использовать then. Вместо этого попробуйте следующее:

this.model.save().always(function(obj) {
 console.log(obj.responseText);
});

Это вызовет вызов вашей функции независимо от того, что произойдет. Тем не менее, вы, вероятно, должны выяснить, что происходит, поэтому вы можете вместо этого добавить успешный и отказоустойчивый ответ для выполнения некоторой отладки:

this.model.save().done(function() {
 // Success case
}).fail(function() {
 // Failure case
});


Поскольку this.model.save возвращает обещание, вы можете сделать следующее:

this.model.save()
 .done(function(response) {
 console.log("Success!");
 })
 .fail(function(response) {
 console.log("Error!");
 });

(Это проще, чем весь бит $.when.)

Я предполагаю, что хотя ваш ответ возвращает код 200, он по-прежнему "терпит неудачу", потому что тип данных ответа не совпадает с ожидаемым (что установлено в атрибуте dataType в $.ajax).


Я большой поклонник использования обещаний, и я думаю, что это обещание означает очень похожие вещи в разных пакетах.

Чтобы ответить на ваш вопрос, чего не было в предыдущих ответах, функция "then" является функцией обещания, функция "когда" является отказоустойчивой, если объект не является обещанием, "когда ( obj)", убедитесь, что это обещание, так что вы можете использовать элегантный xxx.then(success() {}, error() {}).

btw, "отложенный", который сказал машина, - это пакет, который позволяет вам использовать обещание. Чтобы начать понимать обещание и как его использовать. ознакомьтесь с этим руководством. Это объясняет каждую вещь очень четко, это статья, которая сделала меня так в promises. http://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/

Теперь, как говорит машина, кажется, что ваш вызов синхронизации вызывает ошибку, согласно документации API REST, https://parse.com/docs/rest# (дон не знаю, совпадает ли это с базой), сервер ответит на объект JSON для запроса "create" в этом формате:

{"createdAt": "2011-08-20T02:06:57.931Z","objectId": "Ed1nuqPvcm"}

Мое предположение, возможно, ваш сервер не ответил на запрос правильным JSON, поэтому save() считает, что операция завершилась неудачно, потому что не было поля "createAt", событие подумало, что ваш сегмент создал элемент.

licensed under cc by-sa 3.0 with attribution.