async-await小記

這里不會(huì)提到async await的語法,主要是實(shí)踐中的使用,需要用到的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敲定的語法, 為了兼容性在運(yùn)行時(shí)需要轉(zhuǎn)化為瀏覽器熟悉的低版本高兼容語法,將async await轉(zhuǎn)化為regenerator實(shí)現(xiàn),通過babel和插件來轉(zhuǎn)化

  • @babel/core babel編譯的基礎(chǔ)依賴
  • @babel/plugin-transform-regenerator 插件包含regenerator-transform,async await語法通過此轉(zhuǎn)化為regenerator實(shí)現(xiàn)
  • @babel/plugin-transform-runtime 插件將引用的_regenerator等變量引入當(dāng)前文件

一段簡(jiǎn)單的async await代碼轉(zhuǎn)換對(duì)比:

// 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循環(huán)的搭配

最近剛好遇到這類問題,錯(cuò)誤代碼如下

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中是沒有任何數(shù)據(jù)的,因?yàn)閒orEach是不支持async異步行為的
應(yīng)該改用for of或改造forEach
https://blog.csdn.net/Deepspacece/article/details/104342603

generator實(shí)現(xiàn)async-await行為和promise

沒辦法寫下思考過程 直接放結(jié)果吧

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中運(yùn)行

node沒辦法直接運(yùn)行import export語法
如果有的話需要babel插件@babel/plugin-transform-modules-commonjs來轉(zhuǎn)化

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

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

在命令行中直接輸入babel script.js即可編譯

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容