ES6/7异步编程方法总结

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异步编程方法总结)