Как передать jQuery $.ajax вызовы Bluebird promises без отложенного anit-pattern
В настоящее время я использую функцию prom.deferred в основном файле. Это позволяет мне разрешать promises в центральном месте. Я читал, что я могу использовать анти-шаблон, и я хочу понять, почему это плохо.
поэтому в моем файле core.js у меня есть следующие функции:
var getMyLocation = function(location) {
var promiseResolver = Promise.defer();
$.get('some/rest/api/' + location)
.then(function(reponse) {
promiseResolver.resolve(response);
)}
.catch(function(error) {
promiseResolver.reject(error);
});
return promiseResolver.promise;
}
И затем в моем файле getLocation.js у меня есть следующее:
var core = require('core');
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something with data
}).catch(throw error);
После прочтения документов Bluebird и многих сообщений в блоге об отложенном анти-шаблоне я задаюсь вопросом, является ли этот шаблон практичным. Я мог бы изменить это на следующее:
core.js
var getMyLocation = function(location) {
var jqXHR = $.get('some/rest/api/' + location);
return Promise.resolve(jqXHR)
.catch(TimeoutError, CancellationError, function(e) {
jqXHR.abort();
// Don't swallow it
throw e;
});
getLocation.js
var location = core.getMyLocation('Petersburg')
.then(function(response) {
// do something
})
.catch(function(error) {
throw new Error();
});
Я думаю, я смущен тем, что лучший способ иметь центральную библиотеку, которая обрабатывает запросы xhr с использованием jquery для вызовов, но Bluebird для promises.
Ответы
Ответ 1
Вы можете вызвать Promise.resolve
в jQuery thenable и использовать Bluebird:
var res = Promise.resolve($.get(...)); // res is a bluebird Promise
Вы также можете вернуть jQuery promises непосредственно в цепочку Bluebird и усвоить его.
myBluebirdApi().then(function(){
return $.get(...);
}).then(function(result){
// The jQuery thenable was assimilated
});
Ваш код ниже близок, но вам не нужно ловить TimeoutError
, так как jQuery ajax не будет его бросать. Что касается улавливания ошибки отмены. В любом случае, это лучшая практика для того, что вы делаете, если вы когда-либо ожидаете отменить запрос.
Ответ 2
Чтобы преобразовать thenable в обещание Bluebird, вы можете использовать Promise.resolve
следующим образом:
var promise = Promise.resolve($.getJSON(...));
Раздел бонусов:
Большинство функций JQuery AJAX можно использовать, но для вашей информации, если вы хотите преобразовать функцию, ожидающую обратного вызова к обещанию, вы можете использовать Promise.fromNode
. Обратный вызов будет вызван с аргументами err, result
, как это принято в мире Node.js:
var promise = Promise.fromNode(function (callback) { request(url, callback); });
Если обратный вызов не ожидает потенциальной ошибки для его первого аргумента, вы можете обойти это:
var promise = Promise.fromNode(function (callback) {
FB.api(url, function(response) { callback(response ? response.error : "no response", response); });
});