1. ホーム
  2. javascript

[解決済み] ジェネレータによるasync/awaitとES6 yieldの違い

2023-04-02 14:09:09

質問

私はちょうどこの素晴らしい記事を読んでいました。 ジェネレータ " を読んでいて、この関数がジェネレータ関数を処理するためのヘルパー関数であることが明確に強調されています。

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

    function handle(result){
      // result => { done: [Boolean], value: [Object] }
      if (result.done) return Promise.resolve(result.value);

      return Promise.resolve(result.value).then(function (res){
        return handle(generator.next(res));
      }, function (err){
        return handle(generator.throw(err));
      });
    }

    try {
      return handle(generator.next());
    } catch (ex) {
      return Promise.reject(ex);
    }
  }
}

というのは、多かれ少なかれ、私の仮説では async キーワードは async / await . そこで問題なのは、そうだとすると、一体、この await キーワードと yield というキーワードは?は await は常に何かを約束に変えますが、一方 yield はそのような保証をしないのでしょうか?それが私の一番の推測です。

また、どのように async / awaityield のようなもので、ジェネレータはこの記事で 'spawn' 機能について説明しています。 ES7 非同期関数 .

どのように解決するのか?

とは、非常に密接な関係があることがわかりました。 async / await とジェネレータがあります。そして、私が信じているのは async / await は常にジェネレータで構築されます。バベルのトランスパイル方法を見ると async / await :

バベルはこれを受ける。

this.it('is a test', async function () {

    const foo = await 3;
    const bar = await new Promise(resolve => resolve('7'));
    const baz = bar * foo;
    console.log(baz);

});

で、これを次のように変更します。

function _asyncToGenerator(fn) {
    return function () {
        var gen = fn.apply(this, arguments);
        return new Promise(function (resolve, reject) {
            function step(key, arg) {
                try {
                    var info = gen[key](arg);
                    var value = info.value;
                } catch (error) {
                    reject(error);
                    return;
                }
                if (info.done) {
                    resolve(value);
                } else {
                    return Promise.resolve(value).then(function (value) {
                        return step("next", value);
                    }, function (err) {
                        return step("throw", err);
                    });
                }
            }

            return step("next");
        });
    };
}


this.it('is a test', _asyncToGenerator(function* () {   // << now it's a generator

    const foo = yield 3;    //  <<< now it's yield, not await
    const bar = yield new Promise(resolve => resolve(7));
    const baz = bar * foo;
    console.log(baz);

}));

を計算するんだ。

これによって、見た目は async キーワードがそのラッパー関数であるかのように見えますが、もしそうであるなら await に変わるだけです。 yield に変わるだけで、後でネイティブになればもう少し絵になるのでしょう。

これについては、こちらで詳しく解説しています。 https://www.promisejs.org/generators/