6

promise を使用してコーディングする場合、promise のチェーンでずっと前からのデータにアクセスするための正しいパターンは何ですか?

例えば:

do_A.then(do_B).then(do_C).then(do_D).then(do_E_WithTheDataComingFrom_A_And_C_OnlyWhen_D_IsSuccesfullyCompleted)

私の現在の解決策: チェーンを介して単一の JSON 構造を渡し、各ステップでそれを設定します。それについて何か意見はありますか?

4

2 に答える 2

3

これには「正しい」パターンはないと思います。あなたのソリューションはきれいに聞こえますが、少し密結合しています。あなたの状況ではうまくいくかもしれませんが、一般的なパターンとしていくつかの問題があります。

  1. 参加するステップは、コレクター オブジェクトの構造に同意する必要があります。

  2. すべてのステップは、少なくともオブジェクトの転送に参加する必要があります。これは、チェーンが長く、前のデータの必要性が散発的に発生する場合、退屈になる可能性があります。また、これは、自分が作成したものではないステップの挿入に対して柔軟性がありません (チェーンは常に直線的に発生するとは限りません)。

  3. 別の言い方をすると: do_A|B|C|D と do_E があなたの制御下にない限り、それらをボイラープレートでラップしてコレクター オブジェクトをクロージャーに保存し、関数の自然な入力と結果との間で変換する必要があります。関数はあなたのパターンに「入っている」ことはありません。

  4. 一方、関数含まれている場合、ステップ間のデータ依存関係は関数内に効果的に隠されています。これはきれいに見えるかもしれませんが、メンテナンスの問題になる可能性があります。たとえば、これがチーム プロジェクトである場合、入力 do_E が必要とする呼び出しパターンの手がかりがなければ、誰かがステップの順序を変更できると考えるかもしれません。

クロージャーを使用したより簡単なアプローチをお勧めします。

var a, c;

do_A()
.then(function(result) { a = result; return do_B(); })
.then(do_C)
.then(function(result) { c = result; return do_D(); })
.then(function() {
   return do_E_WithTheDataComingFrom_A_And_C_OnlyWhen_D_Succeeds(a, c);
})
.catch(failed);

定義するコレクター オブジェクトはありません。do_A|B|C|D および do_E は、パターンの知識がなくても汎用関数にすることができます。返されるデータが依存しない限り定型句はありません (do_B および do_D)。データの依存関係 (a と c) は明示的です。

于 2015-01-08T06:15:44.113 に答える
2

はい、これは状態とアクションを連鎖させる正しい方法です。

ステートメントのチェーン.thenは非常に一般的であり、通常、パイプを使用する際のビルディング ブロックです。それは約束のまさに核心にあります。

あなたがしていることは、正しくて慣用的です。


好奇心旺盛な方のために、これをお見せしましょう。

これを確認するために、promise の仕様を確認できます。

次のことを確認します。

  1. 連鎖する
  2. 拒否の場合、チェーン内のハンドラーを呼び出さず、
  3. then同じ理由で返された次のプロミスを拒否します
  4. 戻り値を渡して順次実行します。

仕様を使用して、これらを順番に確認しましょう-特に.then

1.連鎖する

7.1 は promise [3.3] を返さなければなりません。

すばらしい、フルフィルメントにも連鎖することを確認しましょう

onFulfilled または onRejected のいずれかが値 x を返す場合、Promise Resolution Procedure >[[Resolve]](promise2, x) を実行します。

thenこれで、promise が解決または拒否されたときに、適切なパラメーターを使用してハンドラーが呼び出されることがわかりました。したがって、解決.then(do_A).then(do_B)を前提として常に機能します。do_A

2. 拒否の場合、チェーン内のハンドラを呼び出さない

7.iv. onRejected が関数ではなく、promise1 が拒否された場合、promise2 も同じ理由で拒否する必要があります。

素晴らしいので、存在するonRejected場合は拒否して呼び出し、存在しない場合はチェーンします。

then3. から返された次の promiseを同じ理由で拒否する

これについては 2 で説明しました。

4. 戻り値を渡して順次実行します。

それがまた

onFulfilled または onRejected のいずれかが値 x を返す場合、Promise Resolution Procedure [[Resolve]](promise2, x) を実行します。

したがって、onFulfilled を設定すると、解決プロセスが実行されます。解決プロセス自体は次のように指示します。

promise 解決手順は、promise と値を入力として受け取る抽象的な操作であり、[[Resolve]](promise, x) と表します。x が thenable の場合、x が少なくともある程度 promise のように動作するという仮定の下で、promise に x の状態を採用させようとします。それ以外の場合、値 x で約束を果たします。

resolvePromise が値 y で呼び出された場合、[[Resolve]](promise, y) を実行します。

ここで、y は x の戻り値です。

すごい!だからそれは動作します。

于 2013-12-03T14:24:47.957 に答える