Skip to content

扩展-babel 对 async 和 await 的转换

babel 对 async 和 await 的转换是比较难以理解的,初学者可以跳过该章节。 大致原理:

  • 转换使用到了生成器和迭代器+状态机(java 学的很深才接触得到)
  • 主要是对生成器和状态机的处理,由于 babel 转换后的代码非常杂多,所以在阅读此类源码的时候有个思想就是--先把握整体,然后简化没必要的代码,去把控核心思想。
js
function A() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(3);
    }, 1000);
  });
}

async function B() {
  const b = await A();
  const c = await A();
  return b + c;
}

B().then((data) => console.log(data));
js
"use strict";

function asyncGeneratorStep(gen, resolve, reject, _next, arg) {
  try {
    var info = gen.next(arg);
    var value = info.value;
  } catch (error) {
    reject(error);
    return;
  }

  if (info.done) {
    resolve(value);
  } else {
    Promise.resolve(value).then((data) => {
      _next(data);
    });
  }
}

//babel对A函数没有进行转换
function A() {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(3);
    }, 1000);
  });
}

//主要是对async和await进行转换,async挂在函数上,那个函数就变成了promise,原理就是内部返回的是promise
function B() {
  var fn = function* () {
    const b = yield A();
    const c = yield A();
    return b + c;
  };
  return new Promise(function (resolve, reject) {
    var gen = fn();
    function _next(value) {
      asyncGeneratorStep(gen, resolve, reject, _next, value);
    }
    _next(undefined);
  });
}

//对这个代码也没有进行转换
B().then(function (data) {
  return console.log(data);
});

思考:

1.为什么 babel 对 async 和 await 进行转换时需要依赖 regenerator 这个库?

因为转换 async 和 await 需要转换为生成器,而生成器也属于新语法,也需要进行转换,我们就需要一个除了 core-js 这个库的另外一个,就是 regenerator 这个库。

MIT License