593

私は次のようなコードを書いていました:

function getStuffDone(param) {           | function getStuffDone(param) {
    var d = Q.defer(); /* or $q.defer */ |     return new Promise(function(resolve, reject) {
    // or = new $.Deferred() etc.        |     // using a promise constructor
    myPromiseFn(param+1)                 |         myPromiseFn(param+1)
    .then(function(val) { /* or .done */ |         .then(function(val) {
        d.resolve(val);                  |             resolve(val);
    }).catch(function(err) { /* .fail */ |         }).catch(function(err) {
        d.reject(err);                   |             reject(err);
    });                                  |         });
    return d.promise; /* or promise() */ |     });
}                                        | }

これはそれぞれ「遅延アンチパターン」または「Promiseコンストラクターアンチパターン」と呼ばれていると誰かが私に言いました。このコードの何が悪いのか、なぜこれがアンチパターンと呼ばれるのですか?

4

3 に答える 3

414

Esailijaによって作成された遅延アンチパターン (現在は明示的構築アンチパターン)は、Promiseを初めて使用する人々が作成する一般的なアンチパターンです。私が最初に Promise を使用したときに作成しました。上記のコードの問題は、チェーンを約束するという事実を利用できないことです。

Promise は連鎖する.thenことができ、Promise を直接返すことができます。のコードは次のgetStuffDoneように書き換えることができます。

function getStuffDone(param){
    return myPromiseFn(param+1); // much nicer, right?
}

Promise は、非同期コードをより読みやすくし、その事実を隠すことなく同期コードのように動作させることを目的としています。Promise は、1 回限りの操作の値に対する抽象化を表し、プログラミング言語のステートメントまたは式の概念を抽象化します。

API をプロミスに変換していて自動的に変換できない場合、またはこの方法でより簡単に表現できる集計関数を作成している場合にのみ、遅延オブジェクトを使用する必要があります。

Esailija の引用:

これは最も一般的なアンチパターンです。Promise をよく理解していない場合や、promise を単なるイベント エミッターやコールバック ユーティリティとして考えていると、この問題に陥りやすくなります。要約してみましょう: プロミスとは、フラット インデントや 1 つの例外チャネルなど、同期コードの失われたプロパティのほとんどを非同期コードに保持させることです。

于 2014-05-22T10:07:00.857 に答える