美文网首页
ES6/7异步编程方法总结

ES6/7异步编程方法总结

作者: 小前seant | 来源:发表于2017-04-12 14:54 被阅读49次

    ES6提供了异步编程的几个新特性:
    本篇主要参考阮一峰大神的ES6文章。

    Promise

    1.基本用法:
    var promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    

    Promise构造函数接受一个函数,该函数的变量为resolve和reject,分别为两个函数,作用为:resolve将promise对象的状态变为resolved,reject将promise对象的状态变为rejected。
    Promise对象创建即执行:

    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      resolve();
    });
    
    promise.then(function() {
      console.log('Resolved.');
    });
    
    console.log('Hi!');
    
    // Promise
    // Hi!
    // Resolved
    
    2.Promise.prototype.then()方法

    生成Promise对象后可通过then()方法来指定resolved、rejected状态下的回调函数。

    promise.then(function(value) {
      // success
    }, function(error) {
      // failure
    });
    
    2.Promise.prototype.catch()方法

    是.then(null, rejection)的别名,用于指定发生错误时的回调函数。
    用于获取promise rejected状态下的回调或者抛出异常。
    Promise对象的错误状态会一直向后传递直到被catch,但并不会被全局捕获。

    3.Promise.all()

    用于将多个Promise实例,包装成一个新的Promise实例。

    var p = Promise.all([p1, p2, p3]);
    
    1. 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
    2. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
    4.Promise.race()

    同样是将多个Promise实例,包装成一个新的Promise实例。

    var p = Promise.race([p1, p2, p3]);
    

    只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

    5.Promise.resolve()

    将一个对象转为Promise对象

    6.Promise.reject()

    将一个对象转为Promise对象,状态是rejected

    Generator

    generator函数类似于状态机

    1.基本用法
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    2.yield语句

    调用generator函数,并不会立即执行,而必须要调用next方法,执行到generator函数中的yield语句后返回。
    yield语句后的表达式作为函数返回值。

    function* f() {
      console.log('执行了!')
    }
    
    var generator = f();
    
    setTimeout(function () {
      generator.next()
    }, 2000);
    
    3.return方法

    可以返回给定的值,并且终结遍历Generator函数。

    4.Generator函数与异步编程

    可采用co模块、thunk函数自动执行

    ES7的async函数

    就是 Generator 函数的语法糖
    如Generator写法:

    var fs = require('fs');
    
    var readFile = function (fileName) {
      return new Promise(function (resolve, reject) {
        fs.readFile(fileName, function(error, data) {
          if (error) reject(error);
          resolve(data);
        });
      });
    };
    
    var gen = function* () {
      var f1 = yield readFile('/etc/fstab');
      var f2 = yield readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    

    写成async函数,就是下面:

    var asyncReadFile = async function () {
      var f1 = await readFile('/etc/fstab');
      var f2 = await readFile('/etc/shells');
      console.log(f1.toString());
      console.log(f2.toString());
    };
    

    比较发现,async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已。

    async函数对 Generator 函数的改进,体现在以下四点:

    • 内置执行器
      Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器。也就是说,async函数的执行,与普通函数一模一样,只要一行。
    • 更好的语义
      async和await,比起*和yield,语义更清楚。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
    • 更广的适用性
      co模块约定,yield命令后面只能是 Thunk 函数或 Promise 对象,而async函数的await命令后面,可以是Promise 对象和原始类型的值(数值、字符串和布尔值,但这时等同于同步操作)。
    • 返回值是 Promise
      async函数的返回值是 Promise 对象,这比 Generator 函数的返回值是 Iterator 对象方便多了。你可以用then方法指定下一步的操作。

    相关文章

      网友评论

          本文标题:ES6/7异步编程方法总结

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