当我们在断点调试程序时,是否经常需要一步步调试程序的处理逻辑,然而在遇到async await函数时,断点的下一步和进入函数会失效。
原因在于async await会被babel转化,造成你调试源码和打包后运行的代码不一致从而不能一步步调试。
- 源代码
async function foo(){
await fn()
console.log(1)
}
async function fn(){
console.log(2)
}
foo()
- 转换后的代码
"use strict";
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function foo() {
return _foo.apply(this, arguments);
}
function _foo() {
_foo = _asyncToGenerator(function* () {
yield fn();
console.log(1);
});
return _foo.apply(this, arguments);
}
function fn() {
return _fn.apply(this, arguments);
}
function _fn() {
_fn = _asyncToGenerator(function* () {
console.log(2);
});
return _fn.apply(this, arguments);
}
foo();
- babel依赖于这两个插件来转换代码
@babel/plugin-transform-async-to-generator
@babel/plugin-transform-regenerator
- chrome浏览器原生支持async await关键字,故可以断点调试
- 在基于vue-cli项目中断点调试,需要设置babel.config.js
const isDev = process.env.NODE_ENV !== 'production'
module.exports = {
presets: [
[
require('@vue/cli-plugin-babel/preset'),
{
exclude: isDev ? ['babel-plugin-transform-async-to-generator', 'babel-plugin-transform-regenerator'] : [],
},
],
],
//...
}
-
在开发环境不转换async awiat函数,这样方便一步步调试,生产环境进行转换兼容低版本浏览器。
-
这是基于vue-cli项目的处理,若是其他项目也是类似的处理逻辑,就是babel在转换代码时 exclude babel-plugin-transform-async-to-generator, babel-plugin-transform-regenerator 这两个插件
-
最终效果
参考文件