async-await小记

这里不会提到async await的语法,主要是实践中的使用,需要用到的dependencies如下

{
  "dependencies": {
    "@babel/core": "^7.11.5",
    "@babel/plugin-transform-modules-commonjs": "^7.10.4",
    "@babel/plugin-transform-regenerator": "^7.10.4",
    "@babel/plugin-transform-runtime": "^7.11.5",
  }
}

async-await

首先async-await是ES7敲定的语法, 为了兼容性在运行时需要转化为浏览器熟悉的低版本高兼容语法,将async await转化为regenerator实现,通过babel和插件来转化

  • @babel/core babel编译的基础依赖
  • @babel/plugin-transform-regenerator 插件包含regenerator-transform,async await语法通过此转化为regenerator实现
  • @babel/plugin-transform-runtime 插件将引用的_regenerator等变量引入当前文件

一段简单的async await代码转换对比:

// from
const run = async () => {
  console.log('begin')
  await delay(1)
  console.log('after 1 s')
}

run()
// to
const run = () => {
  return _regenerator.default.async(function _callee2$(_context2) {
    while (1) switch (_context2.prev = _context2.next) {
      case 0:
        console.log('begin');
        _context2.next = 3;
        return _regenerator.default.awrap(delay(1));

      case 3:
        console.log('after 1 s');

      case 4:
      case "end":
        return _context2.stop();
    }
  }, null, null, null, Promise);
};

run();

与for循环的搭配

最近刚好遇到这类问题,错误代码如下

const entities = []
list.forEach(async (item) => {
    const entity = await this.repo.findOne({
      id: item.id,
    })
    if (entity) {
      entities.push(entity)
    }
})
if (entities.length) {
 // do something
}

这样的逻辑entities中是没有任何数据的,因为forEach是不支持async异步行为的
应该改用for of或改造forEach
https://blog.csdn.net/Deepspacece/article/details/104342603

generator实现async-await行为和promise

没办法写下思考过程 直接放结果吧

import MyPromise from './promise.implement'

const goNext = (generator) => {
  const current = generator.next()
  if (!current.done) {
    const promise = current.value
    promise.then(() => {
      goNext(generator)
    })
  }
}

const delay = (second) => {
  console.log('begin delay')
  return new MyPromise((resolve) => setTimeout(resolve, 1000 * second))
}

const asyncGenerator = function* () {
  yield delay(1)
  yield delay(1)
  console.log('after 2s')
}

const asyncGeneratorIns = asyncGenerator()
goNext(asyncGeneratorIns)
export default class MyPromise {
  constructor(resolveInstance, rejectInstance) {
    let then = null
    const resolve = (res) => {
      then(res)
    }
    try {
      setTimeout(resolveInstance(resolve))
    } catch (err) {
      rejectInstance && rejectInstance(err)
    }
    return {
      then: function (thenInstance) {
        then = thenInstance
      }
    }
  }
}

某种意义上讲async-await算作generator的语法糖也不算过分吧?

node中运行

node没办法直接运行import export语法
如果有的话需要babel插件@babel/plugin-transform-modules-commonjs来转化

在.babelrc中添加需要的plugins或presets

{
  "plugins": [
    "@babel/plugin-transform-regenerator",
    "@babel/plugin-transform-runtime",
    "@babel/plugin-transform-modules-commonjs"
  ]
}

在命令行中直接输入babel script.js即可编译

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容