美文网首页
异步解决方案async & await 及在Gulp和WebPa

异步解决方案async & await 及在Gulp和WebPa

作者: PoWerfulHeart | 来源:发表于2019-09-26 10:08 被阅读0次
    • async & await 是目前为止最好的异步解决方案
    • 从回调函数的形式 =》es6提出的promise =》es8提出的async & await
    • async & await将异步处理做到了极致 => 用同步代码的方式来处理异步

    下面我们来简单的看一个示例:存在异步请求A和B,当A的返回值为success执行B

    var A = () => {
         return new Promise(function(resolve, reject){
                  setTimeout(function(){
                        resolve("success");
                  },3000);
        })
    }
    
    var B = () => {
         return new Promise(function(resolve, reject){
                  setTimeout(function(){
                        resolve("done");
                        //reject("error");
                  },1000);
        })
    }
    
    //Promise + then
    A().then(res => {
            if (res == "success") {
                return B();
            }else{
                console.log("error");
            }
        })
        .then(res => {
            console.log(res);
        })
        .catch(error => {
            console.log(error);
        });
    
    //async
    (async () => {
        try {
            const a = await A();
            if (a == "success") {
                const b = await B();
                console.log(b);
            }else{
                console.log("error");
            }
        } catch (error) {
            console.log(error);
        }
    })();
    

    从上面的示例可以看到async & await的优势:

    • 处理我们常遇到的条件判别和中间值显得异常清晰
    • 处理逻辑不需要再新建匿名函数,大大减少代码量,结构清晰
    • 错误捕获可以使用try/catch结构轻松捕获

    好处说完了,但是因为大佬是es8的新特性,浏览器还没支持。因此下面会介绍怎么在最常用的两种构建工具(gulp和webpack)中配合babel来真正的在我们的生产环境使用它

    webpack篇

    需要用到的包

    npm i --save-dev webpack webpack-cli babel-loader babel-core babel-preset-env babel-plugin-transform-runtime
    npm i --save babel-runtime
    

    webpack遵循commonJs规范,所以我们完全不需要去单独处理各模块的依赖。
    在这个模块化的年代,或许这也是我更钟爱webpack的原因吧

    • webpack.config.js
    // webpack.config.js
    module.exports = {
        entry:{
            main: __dirname + "/index.js"
        },
        output:{
            path: __dirname + "/dist",
            filename: "index.bundle.js"
        },
        module: {
            rules: [
                {
                    test: /\.js$/,
                    use: {
                        loader: "babel-loader"
                    },
                    exclude: /node_modules/
                }
            ]
        }
    }
    
    • .babelrc
    //babel 配置
    {
      "plugins": ["transform-runtime"],       //注意plugin 优先级高于presets
      "presets": [
        ["env"]
      ]
    }
    

    Gulp篇

    1.正确姿势

    这是gulp + browserify正确使用方式,如若你是gulp新手请参照下面的
    2.简单版本
    这里先讲述正确使用方法

    你需要用到的包:

    npm i --save-dev gulp gulp-uglify gulp-buffer vinyl-source-stream babelify babel-core babel-preset-env babel-plugin-transform-runtime browserify
    npm i --save babel-runtime
    

    这里babel-runtime相当于是我们的polyfill,我们使用transform-runtime来动态的去引入需要的部分,避免污染

    很多人会疑问为什么会使用到browserify?下面敲重点:

    • 这得从babel谈起,通俗点说,babel可以将浏览器还没支持的es的新写法编译为浏览器支持的语法。
    • 而es中新增的api则不会被转换,这时候我们就得引入polyfill解决。
    • 而babel转换的代码其实是遵循commonJs规范的,浏览器环境显然不支持,因此再用browserify处理各模块间的关系即可。

    然后又有人问了gulp-buffer vinyl-source-stream是什么鬼?下面还是重点:
    这里我只做基本的介绍,这属于gulp的高级技巧,想刨根问底的童鞋请先了解以下知识

    ​下面是简单介绍​:

    • 首先,gulp使用了vinyl-fs,而vinyl-fs使用的核心是vinyl,vinyl 可以创建一个文件描述对象,通过接口可以取得该文件所对应的数据(Buffer类型)、cwd路径、文件名等等。
    • 因此按照我们入乡随俗的道理,要想使用gulp是不是得把可读流转换为vinyl file object?那么vinyl-source-stream(可以将普通流转换为vinyl file object stream),vinyl-source-buffer(可以将普通流转换为vinyl file object buffer)它们就来了,按需使用即可。
    • vinyl file object拥有一个属性来表示里面是buffer还是流,gulp默认使用buffer。像一些gulp的插件也是基于buffer的实现(比如gulp-uglify),因此gulp-buffer它来了。反之基于流的插件也可以使用gulp-streamify转换成流再进行处理。
    • gulpfile.js
    //gulpfile.js
    var gulp = require('gulp'),
      babelify = require('babelify'),
      notify = require('gulp-notify'),     //按需使用
      browserify = require('browserify'),
      buffer = require('gulp-buffer'),   //vinyl-buffer也可
      uglify = require('gulp-uglify'),
      source = require('vinyl-source-stream');   //vinyl-source-buffer  按需使用
    
      gulp.task('default', function () {
        browserify('./index.js')
        .transform("babelify", {plugins: ["transform-runtime"],presets: [["env"]]})     //babel处理
        .bundle()       //处理模块依赖
        .pipe(source("index.js"))      //转换为vinyl文件对象
        .pipe(buffer())          //转换为buffer以便进行代码压缩
        .pipe(uglify())
        .pipe(gulp.dest('./dist'))
        .pipe(notify({
            message: 'javascript compile complete'
        }));
    });
    

    2.简单版本,不推荐

    gulp-browserify已经被官方拉入黑名单,作者也停止维护了。新手入门可以使用

    你需要用到的包

    npm i --save-dev gulp gulp-babel babel-core babel-preset-env babel-plugin-transform-runtime gulp-browserify
    npm i --save babel-runtime
    

    gulp-browserify来自动处理模块依赖

    • gulpfile.js
    //gulpfile.js
    var gulp = require('gulp'),
      babel = require('gulp-babel'),
      notify = require('gulp-notify'),
      browserify = require('gulp-browserify');
    
      gulp.task('default', function () {
       gulp.src('./index.js')
           .pipe(babel())
           .pipe(browserify())
           .pipe(gulp.dest('./dist'))
           .pipe(notify({
            message: 'javascript compile complete'
          }));
    });
    
    // babel 配置同webpack篇
    

    参考文章:
    6-reasons-why-javascripts-async-await-blows-promises

    相关文章

      网友评论

          本文标题:异步解决方案async & await 及在Gulp和WebPa

          本文链接:https://www.haomeiwen.com/subject/vfnductx.html