這里不會(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/corebabel編譯的基礎(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即可編譯