zoukankan      html  css  js  c++  java
  • typescript在ES3(IE7)环境下使用async、await

    因为公司产品需要搞个Web App,但是又需要兼容IE7,这时候整个应用会非常复杂,尤其是在处理异步的时候,在我的选择中有两个方案

    1. callback方案
    2. 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配置文件
    $ .
    ode_modules.bin	sc --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的方法

    typescript在ES3(IE7)环境下使用async、await

  • 相关阅读:
    Python字典dict对象方法总结
    PythonString字符串的相关方法
    Mysql5.7.20使用group by查询(select *)时出现错误修改sql mode
    HtmlTestRunner无法生成HTML报告问题
    话说 type 之 record 记录的使用技巧 F#
    Silverlight OOB 获取桌面可视尺寸 F# PInvoke
    目前让 F# 支持 Silverlight 5 的解决方案(包括 lazy 不可用)
    话说 type 之 let 绑定与 val 显式字段 F#
    这两天自己模仿写的一个Asp.Net的显示分页方法 附加实体转换和存储过程 带源码下载
    Asp.net 在三层架构中事务的使用
  • 原文地址:https://www.cnblogs.com/ystrdy/p/10283534.html
Copyright © 2011-2022 走看看