我的目标是将async / await编译成Bluebird承诺,同时将性能影响降至最低。
babel-plugin-transform-async-to-module-method
似乎是编译async / await到Bluebird的最常用方法,但是它减慢了我的应用程序约10-20%,这是不可接受的。我怀疑这很多都是由于再生器,这似乎是babel-plugin-transform-async-to-module-method
所必需的。
例如,我在index.js中有这段代码:
var Promise = require('bluebird');
async function foo() {
console.log('foo');
await Promise.delay(500);
console.log('bar');
}
foo();
和这个package.json:
{
"name": "async-regenerator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "browserify index.js -t babelify --outfile bundle.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-plugin-transform-async-to-module-method": "^6.7.0",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.2.0",
"browserify": "^13.0.0"
},
"dependencies": {
"bluebird": "^3.3.5"
},
"browserify": {
"transform": [
"babelify"
]
},
"babel": {
"presets": [
"es2015"
],
"plugins": [
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}
}
使用npm run build
进行编译确实有效,但是运行bundle.js会产生错误:
ReferenceError: regeneratorRuntime is not defined
将再生器添加到package.json会修复错误:
{
"name": "async-regenerator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "browserify index.js -t babelify --outfile bundle.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-plugin-transform-async-to-module-method": "^6.7.0",
"babel-plugin-transform-runtime": "^6.7.5",
"babel-preset-es2015": "^6.6.0",
"babelify": "^7.2.0",
"browserify": "^13.0.0"
},
"dependencies": {
"babel-runtime": "^6.6.1",
"bluebird": "^3.3.5"
},
"browserify": {
"transform": [
"babelify"
]
},
"babel": {
"presets": [
"es2015"
],
"plugins": [
[
"transform-runtime",
{
"polyfill": false,
"regenerator": true
}
],
[
"transform-async-to-module-method",
{
"module": "bluebird",
"method": "coroutine"
}
]
]
}
}
然后bundle.js成功运行,但它使我的构建体积增大了100kb,并可能引入上述性能问题。
我的问题是,为什么甚至还需要再生器呢?我的目标浏览器(Chrome和Firefox)支持生成器,因此必须有一些方法才能使用本机生成器,对吧?我不知道这是否能解决我的性能问题,但我想尝试一下。
我知道有一些其他类似的async / await方法:
如果我忽略了您认为尝试的其他方法,请告诉我。
我将示例代码放在https://github.com/dumbmatter/babel-async-await-regenerator上 - 欢迎PR!
答案 0 :(得分:8)
您可以使用async-to-generator插件。但不幸的是,es2015预设仍将改变发电机,因此您必须修改es2015预设。您可以使用modify-babel-preset
,或者只是简单地展开您的babel配置中的预设。
"babel": {
"plugins": [
"transform-es2015-template-literals",
"transform-es2015-literals",
"transform-es2015-function-name",
"transform-es2015-arrow-functions",
"transform-es2015-block-scoped-functions",
"transform-es2015-classes",
"transform-es2015-object-super",
"transform-es2015-shorthand-properties",
"transform-es2015-duplicate-keys",
"transform-es2015-computed-properties",
"transform-es2015-for-of",
"transform-es2015-sticky-regex",
"transform-es2015-unicode-regex",
"check-es2015-constants",
"transform-es2015-spread",
"transform-es2015-parameters",
"transform-es2015-destructuring",
"transform-es2015-block-scoping",
"transform-es2015-typeof-symbol",
"transform-es2015-modules-commonjs",
"transform-async-to-generator"
]
}