Подтвердить что ты не робот

Как передать 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.

4b9b3361

Ответ 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); });
});