异步解决方案async & await 及在gulp和webpack中的使用

  • 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

猜你喜欢

转载自blog.csdn.net/NewObjectNotFound/article/details/101461116