typescript在ES3(IE7)環境下使用async、await
因為公司產品需要搞個Web App,但是又需要兼容IE7,這時候整個應用會非常復雜,尤其是在處理異步的時候,在我的選擇中有兩個方案
- callback方案
- async/await
經過衡量以後,決定使用async/await方案
配置typescript環境
$ mkdir typescript-async # 新建項目目錄 $ cd typescript-async # 進入項目目錄 $ npm init -y # 初始化項目 $ npm i webpack --save-dev # 安裝webpack $ npm i ts-loader --save-dev # 安裝loader $ npm i typescript --save-dev # 安裝typescript編譯器 $ npm i es3ify-webpack-plugin --save-dev $ touch webpack.dev.js # 新建webpack配置文件 $ .\node_modules\.bin\tsc --init # 創建typescript配置文件
webpack.dev.js
改為如下
const path = require(‘path‘); const es3ifyPlugin = require(‘es3ify-webpack-plugin‘); module.exports = { mode: ‘development‘, entry: ‘./src/index.ts‘, output: { path: path.resolve(__dirname, ‘build‘), filename: ‘[name].js‘, }, module: { rules: [{ test: /\.ts$/, use: [‘ts-loader‘], }], }, resolve: { extensions: [‘.ts‘], }, devtool: "source-map", plugins: [ new es3ifyPlugin(), ], };
package.json
修改為如下
{
// ...
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1",
+ "start": "webpack --config webpack.dev.js"
}
// ...
}
tsconfig.json
修改為如下
{ "compilerOptions": { // ... - "target": "es5", + "target": "es3", // ... - "strict": true, + "strict": false, // ... } }
配置測試
$ mkdir src
$ touch src/index.ts # 新建文件
index.ts
改為如下
const log = (text: string) => console.log(text);
for (let i = 0; i < 5; i++) {
log(String(i));
}
編譯源碼
$ npm start
只要沒有報錯,就可以在看到build/main.js
文件,這個文件就是編譯後的結果,那麽typescript的編譯環境就搭建好了
支持async、await
$ npm i es6-promise --save # 安裝promise polyfill
webpack.dev.js
改為如下
module.exports = {
// ...
resolve: {
- extensions: [‘.ts‘],
+ extensions: [‘.js‘, ‘.ts‘],
},
// ...
};
tsconfig.json
修改為如下
{
"compilerOptions": {
// ...
+ "lib": [
+ "dom",
+ "es2015",
+ "scripthost"
+ ],
// ...
}
}
src/index.ts
改為如下
import "es6-promise/auto"; // 低版本瀏覽器支持promise
const delay = (time: number) => new Promise(resolve => setTimeout(resolve, time));
(async () => {
await delay(1000);
alert(‘done.‘);
})();
編譯源碼
$ npm start
編譯成功,async/await在ES3的環境下可以使用了
優化helpers代碼
什麽是helpers代碼?直接看例子,有以下代碼
src/index.ts
改為如下
import "es6-promise/auto";
import delayA from "./a";
import delayB from "./b";
const delay = (time: number) => new Promise(resolve => setTimeout(resolve, time));
(async () => {
await delay(1000);
alert(‘1‘);
await delayA(1000);
alert(‘2‘);
await delayB(1000);
alert(‘3‘);
})();
src/a.ts
改為如下
const delay = (time: number) => new Promise(resolve => setTimeout(resolve, time));
async function delayA(time: number) {
await delay(time);
}
export default delayA;
src/b.ts
改為如下
const delay = (time: number) => new Promise(resolve => setTimeout(resolve, time));
async function delayB(time: number) {
await delay(time);
}
export default delayB;
編譯源碼
$ npm start
查看生成後的代碼build/main.js
,會看到有以下部分
// 省略以上代碼
/************************************************************************/
/******/ ({
/***/ "./src/a.ts":
/*!******************!* !*** ./src/a.ts ***!
\******************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
// ...省略
};
var __generator = (this && this.__generator) || function (thisArg, body) {
// ...省略
};
exports.__esModule = true;
var delay = function (time) { return new Promise(function (resolve) { return setTimeout(resolve, time); }); };
function delayA(time) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, delay(time)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
}
exports["default"] = delayA;
/***/ }),
/***/ "./src/b.ts":
/*!******************!* !*** ./src/b.ts ***!
\******************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
// ...省略
};
var __generator = (this && this.__generator) || function (thisArg, body) {
// ...省略
};
exports.__esModule = true;
var delay = function (time) { return new Promise(function (resolve) { return setTimeout(resolve, time); }); };
function delayB(time) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, delay(time)];
case 1:
_a.sent();
return [2 /*return*/];
}
});
});
}
exports["default"] = delayB;
/***/ }),
/***/ "./src/index.ts":
/*!**********************!* !*** ./src/index.ts ***!
\**********************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
// ...省略
};
var __generator = (this && this.__generator) || function (thisArg, body) {
// ...省略
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var _this = this;
exports.__esModule = true;
__webpack_require__(/*! es6-promise/auto */ "./node_modules/es6-promise/auto.js");
var a_1 = __importDefault(__webpack_require__(/*! ./a */ "./src/a.ts"));
var b_1 = __importDefault(__webpack_require__(/*! ./b */ "./src/b.ts"));
var delay = function (time) { return new Promise(function (resolve) { return setTimeout(resolve, time); }); };
(function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, delay(1000)];
case 1:
_a.sent();
alert(‘1‘);
return [4 /*yield*/, a_1["default"](1000)];
case 2:
_a.sent();
alert(‘2‘);
return [4 /*yield*/, b_1["default"](1000)];
case 3:
_a.sent();
alert(‘3‘);
return [2 /*return*/];
}
});
}); })();
/***/ })
/******/ });
//# sourceMappingURL=main.js.map
可以看到大量的重復的__awaiter
、__generator
代碼,這個就是helpers代碼,我們需要去掉重復的代碼,處理的方式有以下兩種
方法1:importHelpers開關
$ npm i tslib --save # 安裝tslib
tsconfig.json
修改為如下
{
"compilerOptions": {
// ...
+ "importHelpers": true,
// ...
}
}
註:上面這種方式需要支持Object.defineProperty
這個方法,但是ES3環境不支持,所以ES3環境下不能用這個方式
方法2:noEmitHelpers開關
$ npm i tslib --save # 安裝tslib
tsconfig.json
修改為如下
{
"compilerOptions": {
// ...
+ "noEmitHelpers": true,
// ...
}
}
src/index.ts
改為如下
import "es6-promise/auto";
+ import ‘tslib/tslib‘;
// ...
編譯源碼
$ npm start
查看生成後的代碼build/main.js
,可以看到重復的部分沒有了
以上就是整個在ES3環境下使用async/await的方法,如果有不懂的地方可以發郵件[email protected]聯系我
typescript在ES3(IE7)環境下使用async、await
typescript在ES3(IE7)環境下使用async、await