51

重複の可能性:
Javascript の Deferred、Promise、Future の違いは何ですか?

最近、私は自分の JavaScript アプリケーションの品質を向上させる努力をしています。

私が採用した 1 つのパターンは、別の「データ コンテキスト」オブジェクトを使用して、アプリケーションのデータをロードすることです (以前は、ビュー モデルで直接これを行っていました)。

次の例は、クライアントで初期化されたデータを返します。

var mockData = (function($, undefined) {

    var fruit = [
        "apple",
        "orange",
        "banana",
        "pear"
        ];

    var getFruit = function() {
        return fruit;
    };

    return {
        getFruit: getFruit
    }
})(jQuery);

ほとんどの場合、サーバーからデータをロードするため、すぐに応答を返すことはできません。API でこれを処理する方法には、次の 2 つのオプションがあるようです。

  1. コールバックの使用
  2. 約束を返す。

以前は、常にコールバック アプローチを使用していました。

var getFruit = function(onFruitReady) {
    onFruitReady(fruit);
};

// ...

var FruitModel = function(dataContext, $) {
    return {
        render: function() {
            dataContext.getFruit(function(fruit) {
                // do something with fruit
            });
        }
    };
};

ただし、特に複雑な JavaScript アプリケーションを構築する場合は、コールバック地獄に陥る可能性があることがわかります。

その後、Promises デザイン パターンに出会いました。呼び出し元にコールバックを提供するよう要求する代わりに、観察できる「約束」を返します。

var getFruit = function() {
    return $.Deferred().resolve(fruit).promise();
};

// ...
dataContext.getFruit().then(function(fruit) {
    // do something with fruit
});

このパターンを使用する利点は明らかです。特に、wait複数の遅延オブジェクトを使用できるため、単一ページ アプリケーションの初期化データをロードするときに非常に便利です。

ただし、怒りでどちらかを使い始める前に、各パターンの長所と短所を理解したいと思っています. これが他のライブラリの方向性であるかどうかにも興味があります.jQueryの場合はそうです。

これは、テストに使用しているフィドルへのリンクです。

4

2 に答える 2

18

Promise はバックグラウンドでのコールバックにも依存しているため、実際には 1 対 2 というわけではありません。

コールバックの利点は、プレーンな JavaScript (たとえば ajax 呼び出し) で簡単に実装できることです。

Promise には追加の抽象化レイヤーが必要です。これは通常、ライブラリに依存することを意味します (既に jQuery を使用しているため、この場合は問題になりません)。複数の非同期呼び出しを並行して処理する場合に最適です。

于 2013-01-02T19:26:37.957 に答える
3

@Pointy がリンクしたjQuery ドキュメントを読むと、Deferred API では、リクエストの完了時に呼び出される複数の関数を指定できることが違いのように思えます。

jQuery 1.5 の時点で、エラー (失敗)、成功 (完了)、および完了 (jQuery 1.6 以降は常に) のコールバック フックは、先入れ先出し管理キューです。つまり、各フックに複数のコールバックを割り当てることができます。これらの $.ajax() コールバック フック用に内部的に実装されている Deferred オブジェクト メソッドを参照してください。

参照: deferred.then()

于 2013-01-02T19:35:01.573 に答える