Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

语法糖解析系列之——async/await #14

Open
MyPrototypeWhat opened this issue Dec 25, 2021 · 0 comments
Open

语法糖解析系列之——async/await #14

MyPrototypeWhat opened this issue Dec 25, 2021 · 0 comments

Comments

@MyPrototypeWhat
Copy link
Owner

async/await 实现原理

  • yield/generator

    • yield* 后面可跟String\Array\Generator可迭代的对象
    function* foo() {
      yield* [1, 2];
      yield* "12";
      yield* [
        function* () {
          yield 1;
        },
        function* () {
          yield 2;
        },
      ];
    }
    const f=foo()
    console.log(g.next());//{value: 1, done: false}
    console.log(g.next());//{value: 2, done: false}
    console.log(g.next());//{value: "1", done: false}
    console.log(g.next());//{value: "2", done: false}
    console.log(g.next());//{value: ƒ*, done: false}
    console.log(g.next());//{value: ƒ*, done: false}
    console.log(g.next());//{value: undefined, done: true}
    • yield 后面跟generator 并不会执行generator函数
  • 现有写法

    const f1=async ()=>{
        console.log('f1')
        const data=await f2()
        console.log('data',data)
    }
    const f2=async ()=>{
        return await 'f2'
    }
  • babel之后

    "use strict";
    
    function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key,arg) {
      try {
        // 执行next
        var info = gen[key](arg);
        var value = info.value;
      } catch (error) {
        reject(error);
        return;
      }
      if (info.done) {
    		// 更改promise状态
        resolve(value);
      } else {
        // 如果value是一个promise,会在执行promise改变状态之后执行_next/_throw
        Promise.resolve(value).then(_next, _throw);
      }
    }
    
    function _asyncToGenerator(fn) {
      return function () {
        // 保存this和参数
        var self = this,
          args = arguments;
        return new Promise(function (resolve, reject) {
          var gen = fn.apply(self, args);
          function _next(value) {
            asyncGeneratorStep(gen, resolve, reject, _next, _throw,"next",value);
          }
          function _throw(err) {
            asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
          }
          // 每次执行前先执行一次next
          _next(undefined);
        });
      };
    }
    
    const f1 = /*#__PURE__*/ (function () {
      // f1的函数体被变成generator函数并被_asyncToGenerator包裹
      var _ref = _asyncToGenerator(function* () {
        console.log("f1");
        // await被编译成yield
        const data = yield f2();
        console.log("data",data); // f2
      });
    
      return function f1() {
        // 保证this指向正确
        return _ref.apply(this,arguments);
      };
    })();
    
    const f2 = /*#__PURE__*/ (function () {
      var _ref2 = _asyncToGenerator(function* () {
        return yield "f2";
      });
    
      return function f2() {
        return _ref2.apply(this,arguments);
      };
    })();
    f1();
  • _asyncToGenerator返回一个函数执行后,返回一个promise是为了在done=false时时候,被Promise.resolve包裹(上文执行到yield f2()时,f1valuef2返回的promise),从而等待异步操作完成之后再执行next

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant