Обертывание jquery $.ajax в RSVP. Обломки взрывает все приложение
ОБНОВЛЕНИЕ 1: Добавлен еще один неожиданно нерабочий пример кода
ОБНОВЛЕНИЕ 2: я вернулся к началу и сделал переписать мою недавно реализованную логику - теперь она работает
я использую Ember.js
наряду с (сейчас не рекомендуется) ember-app-kit
макет и условности. Основные версии библиотек:
DEBUG: -------------------------------
DEBUG: Ember : 1.4.0
DEBUG: Handlebars : 1.3.0
DEBUG: jQuery : 2.1.0
DEBUG: -------------------------------
Поскольку у меня было намерение сохранить все свои Ajax
запросы в одном месте, я придумал AjaxManager
класс, который обработал все мои запросы с помощью следующего кода:
function async (requestObj, successCallback, errorCallback) {
requestObj.async = true; // just to be sure it's really asynchronous
return $.when($.ajax(requestObj)).then(successCallback, errorCallback);
}
Теперь, когда я продвинулся дальше и мой код эволюционировал, я хотел обернуть это в Ember.RSVP.Promise
объект, просто для удобства при вызове его из моего model
крючки и тому подобное. Итак, я сделал следующее:
function promisedAsync (requestObj) {
requestObj.async = true; // just to be sure it's really asynchronous
return new Ember.RSVP.Promise(function (resolve, reject) {
requestObj.success = function (data) {
resolve(data);
};
requestObj.error = function () {
reject(arguments)
};
$.ajax(requestObj);
});
}
Но то, что происходит сейчас, это то, что мой первый Ember.RSVP.Promise
разрешается, как и ожидалось, но все дальнейшие Обещания остаются нерешенными / не отвергнутыми, что означает, что оно вешает все приложение и заставляет Chrome взрывать поток страниц и собирать все больше и больше ОЗУ (которое часто суммируется и может быть остановлено только при остановке процесса),
Итак, в основном Ember.RSVP.Promise
взрывается $.ajax
! Я также попробовал это с Ember.RSVP.defer()
или используя jqXHR.beforeSend
метод получения обещания / отложенного разрешения / отклонения, но он всегда один и тот же: первое обещание разрешается / отклоняется, все остальные зависают и никогда не появятся снова...
ОБНОВЛЕНИЕ 1:
Я попробовал это с простой XMLHttpRequest
, оставляя jQuery.ajax
позади и RSVP.defer()
отложенный объект, но он дает мне тот же результат:
var set = Ember.set,
get = Ember.get,
RSVP = Ember.RSVP;
//....
// some application code
//...
promisedAsync: function (ajaxData) {
var url = get(ajaxData, 'url'),
method = get(ajaxData, 'type').toUpperCase(),
xhr = new XMLHttpRequest(), // developing on Chrome, no IE needed (until now) :)
data = get(ajaxData, 'data'),
deferred = RSVP.defer();
if (method === 'GET') {
url = this._prepareUrl(url, data); // takes the data and concatenates it so that the params are in the URL
}
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var response;
try {
response = JSON.parse(xhr.responseText);
if (xhr.status === 200) {
deferred.resolve(response);
} else {
deferred.reject(response);
}
} catch (e) {
deferred.reject(e);
}
}
};
xhr.onabort = function () {
deferred.reject('aborted');
};
if (method === 'GET') {
xhr.send(null);
} else {
xhr.send(data);
}
return deferred.promise;
}
ОБНОВЛЕНИЕ 2:
Когда у меня закончились идеи, и из консоли инструментов разработчика не появилось ни одного символа кода ошибки или чего-то еще, я, наконец, отменил свою огромную кучу кода и сделал полный сброс. Я реализовал код меньшими шагами / коммитами / чанками, и теперь он работает! Я не имею ни малейшего представления, что стало причиной этой проблемы, так как код почти такой же...
Кто-нибудь сталкивался с подобной проблемой или может дать мне совет или подсказку в правильном направлении?
2 ответа
В конце концов, только перезапись и перезапись сделали свое дело - извините за то, что все ваши будущие разработчики столкнулись с чем-то похожим, но у меня нет другого решения, кроме как сделать это снова. Это сводило меня с ума!
Я приму этот ответ как решение моей проблемы, чтобы его можно было закрыть.
Я также не вижу никакой проблемы, для тестирования было бы хорошо обернуть это в Ember.run
заявление, вот копия того, как Ember Data делает это (почти так же, как у вас).
ajax: function(url, type, hash) {
var adapter = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
hash = adapter.ajaxOptions(url, type, hash); // this is your requestObj
hash.success = function(json) {
Ember.run(null, resolve, json);
};
hash.error = function(jqXHR, textStatus, errorThrown) {
Ember.run(null, reject, adapter.ajaxError(jqXHR));
};
Ember.$.ajax(hash); // this is the same thing as $.ajax
}, "DS: RestAdapter#ajax " + type + " to " + url); // they name their promise
}