11

yieldおそらく「co」を使用して、promiseの値を取得する方法を見つけようとしています:

function *(){
    var someVar = yield functionThatReturnsAPromise();
}

呼び出された関数はジェネレーターではなく、通常の関数です。上記でsomeVar == Promise、 ですが、解決された値が必要です。coまたは他のライブラリにはこれを行う方法がありますか?

4

2 に答える 2

7

通常、yield は、ジェネレーターの呼び出し関数と同じ値を、一時停止された実行 (yield 関数の左側) に返します。この単純な例では、1 から 5 まで数えます。yield の入力は、ジェネレーター関数およびジェネレーターの実行パスへの yield の出力です。

function* inc() {
    var g = 0; 
    while (true) {
      g = yield g + 1;
    }
}

var incGen = inc();
for (i = incGen.next().value; i <= 5; i = incGen.next(i).value) {
  console.log(i);  //                                ^ input of generator is last output
}

ただし、呼び出し元の関数はジェネレーターを呼び出すこともできますが、最後の生成の出力を別の値に置き換えるか、ジェネレーターの実行に例外をスローすることさえあります。promise の場合、promise を返す関数は、promise 自体の代わりにその promise の結果を生成する場合があります。したがって、この場合:

var someVar = yield functionThatReturnsAPromise();
     ^ output  !=   ^ input

入力としてプロミスを受け取り、解決されたプロミスをジェネレータ関数への出力として返す関数としてyieldを機能させたい場合。

たまたまcoあなたのためにこれを行うことができます。必要なのは、ジェネレーター関数を関数にフィードすることだけですco

co(function *(){
    var someVar = yield functionThatReturnsAPromise();
})

これがどのように機能するかをよりよく理解するために、co と同じことを行う関数の例を次に示します。

function async(makeGenerator){
  return function (){
    var generator = makeGenerator.apply(this, arguments)

    function handle(result){
      if (result.done) return result.value

      return result.value.then(function (res){
        return handle(generator.next(res))  // <- sets output of yield to the promise result
      }, function (err){                    //    and returns input promise 
        return handle(generator.throw(err)) // <- throw promise exception to generator function
      })
    }

    return handle(generator.next()) // <- first time call, input of yield is a promise
  }
}

情報源は、フォーブス リンデセイのこの概念に関する有名なプレゼンテーションからのものです。

于 2014-02-18T07:22:13.510 に答える