美文网首页
async-await小记

async-await小记

作者: Matthew5 | 来源:发表于2020-09-02 15:52 被阅读0次

    这里不会提到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即可编译

    相关文章

      网友评论

          本文标题:async-await小记

          本文链接:https://www.haomeiwen.com/subject/unhwsktx.html