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