4

人気のあるJavaScriptモジュールQは、据え置き/約束/先物の概念を実装しています。主にnode.jsで使用されていると思いますが、ブラウザの使用もサポートしています。node.jsで使用しています。

シーケンシャルコールを実行するには、あるプロミスを次のプロミスにチェーンしますthen()が、ループでは、この擬似コードと同じことを行うのが難しいと感じるよりも直感に反する可能性があります。

forever {
    l = getline();

    if (l === undefined) {
        break;
    } else {
        doStuff(l);
    }
}

Qのドキュメントには、非常によく似た例が含まれています。

var funcs = [foo, bar, baz, qux];

var result = Q.resolve(initialVal);
funcs.forEach(function (f) {
    result = result.then(f);
});
return result;

しかし、この例を私の問題に適応させるために多くの方法を試みても、私はまったく成功していません。

サンプルコードとは異なり、配列を反復処理していませんが、終了条件が満たされるまでループしたいと考えています。また、私はいつも同じ関数を呼び出します。私の関数は、前の結果を次の呼び出しのパラメーターとして受け取りません。各呼び出しは引数を取りませんが、戻り値によってループを続行するかどうかが決まります。

これらの一見些細な違いは、ある種の乗り越えられない精神的ブロックを引き起こしています。これで、多くの人が約束を理解するのに苦労している理由がわかります。

4

2 に答える 2

6

覚えておくべき重要なことは、thenコールバックからプロミスを返すと、既存のプロミスが置き換えられるということです。ループ本体で実行したいことのチェーンを1回繰り返した後、promiseを解決する値を返すか、ループの本体を再度実行する新しいPromiseを返すという考え方です。

function iterateUntil(endValue){
  // This line would eventually resolve the promise with something matching
  // the final ending condition.
  return Q.resolve('some value')
    .then(function(value){
      // If the promise was resolved with the loop end condition then you just
      // return the value or something, which will resolve the promise.
      if (value == endValue) return value;

      // Otherwise you call 'iterateUntil' again which will replace the current
      // promise with a new one that will do another iteration.
      else return iterateUntil(endValue);
    });
}
于 2013-02-17T03:48:00.297 に答える
0

これはQ:同期forループに固有のものではありません。

于 2013-03-03T11:36:39.530 に答える