web-dev-qa-db-ja.com

延期されたアンチパターンなしでBluebirdpromiseにjQuery $ .ajax呼び出しをキャストする方法

現在、コアファイルでpromise.deferredを使用しています。これにより、中央の場所で約束を解決することができます。アンチパターンを使用している可能性があることを読んでいて、なぜそれが悪いのかを理解したいと思います。

だから私の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();
    });

呼び出しにjqueryを使用してxhrリクエストを処理する中央ライブラリを作成する最善の方法は何かと混乱していると思いますが、PromiseはBluebirdです。

20
Jeff

あなたは呼び出すことができます Promise.resolve jQueryでthenableし、Bluebirdに同化させます。

var res = Promise.resolve($.get(...)); // res is a bluebird Promise

また、Bluebirdチェーン内でjQueryのpromiseを直接返し、それを同化させることもできます。

myBluebirdApi().then(function(){
    return $.get(...);
}).then(function(result){
    // The jQuery thenable was assimilated
});

以下のコードは近いですが、jQuery ajaxはそれらをスローしないため、TimeoutErrorをキャッチする必要はありません。キャンセルエラーのキャッチも。とにかく、リクエストをキャンセルする必要があると予想される場合は、これがベストプラクティスです。

20

ThenableをBluebirdpromiseに変換するには、次のように呼び出すことができます Promise.resolve

var promise = Promise.resolve($.getJSON(...));

ボーナスセクション:

ほとんどのJQuery AJAX関数はその後可能ですが、参考までに、コールバックを期待する関数をpromiseに変換する場合は、 Promise.fromNode を使用できます。 =。コールバックは、Node.jsの世界での慣例として、引数err, resultを使用して呼び出されます。

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); });
});
4
Flimm