Promise

Promise

Promise简介

Promise有三种状态,Pending(进行中)、Resolved(已完成)、Rejected(已失效)。 Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected

promise对象规定的方法(这里的 thencatch)以外的方法都是不可以使用的。

var myFirstPromise = new Promise(function(resolve, reject){
    console.log('1>>');
    setTimeout(function(){
        resolve("成功!>>>");
    }, 1000);
});

myFirstPromise.then(function(successMessage){
    console.log("Yeah! " + successMessage);
});
//1>>
//1000毫秒后打印下面内容
//Yeah! 成功!>>>

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从Pending变为Resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject同理。

一般对结果进行判断,然后决定是调用哪个函数。

var promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

失败的话,会在调用catch方法后的回调函数。

function asyncFunction() {
    return new Promise(function (resolve, reject) {
        reject ('reject -- Hello world');
    });
}
asyncFunction().then(function (value) {
    console.log(value);   
}).catch(function (error) {
    console.log('err>>>',error);
});

Promise.prototype.then()

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法。

var p1=new Promise(function(resolve,reject){
    setTimeout(()=>{
        console.log('p1>>>');
        resolve('hei')
    },1000);
});

p1.then(
    function(res){
        console.log('res>>',res);
        return 'boy';
    }
).then(function(res){
    console.log('Good');
    console.log('res>>',res);
}).catch(err=>console.log('err>',err))


// p1>>>
// res>> hei
// Good
// res>> boy

前一个then方法的如果有返回值,会作为下一个then方法的参数。

使用promise.then(onFulfilled, onRejected)的话,在 onFulfilled中发生异常的话,在 onRejected 中是捕获不到这个异常的。

promise.then(onFulfilled).catch(onRejected) 的情况下,then 中产生的异常能在 .catch 中捕获。

Promise.prototype.catch

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。

如果异步操作抛出错误,状态就会变为Rejected,就会调用catch方法指定的回调函数,处理这个错误。

var promise = new Promise(function(resolve, reject) {
  throw new Error('test');
});
promise.catch(function(error) {
  console.log(error);
});
// Error: test

Promise.all()

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

Promise.all方法接受一个数组作为参数,p1p2p3都是Promise对象的实例。

所有参数的状态都为fulfilledp的状态才会是fulfilled。 或者其中一个是rejectedp的状态就会变成rejected

// 生成一个Promise对象的数组
var promises = [2, 3, 5, 7, 11, 13].map(function (id) {
  return getJSON("/post/" + id + ".json");
});

Promise.all(promises).then(function (posts) {
  // ...
}).catch(function(reason){
  // ...
});

Promise.race()

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

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);
p.then(response => console.log(response));
p.catch(error => console.log(error));

如果5秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。

Promise.resolve()

Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

Promise.reject()

Promise.reject(reason)方法也会返回一个新的 Promise 实例,该实例的状态为rejected

var p = Promise.reject('出错了');
// 等同于
var p = new Promise((resolve, reject) => reject('出错了'))

p.then(null, function (s) {
  console.log(s)
});
// 出错了

done()

Promise对象的最后可以执行一个done方法,

asyncFunc()
  .then(f1)
  .catch(r1)
  .then(f2)
  .done();

done都会捕捉到任何可能出现的错误,并向全局抛出。

finally()

finally方法用于指定不管Promise对象最后状态如何,都会执行的操作。它与done方法的最大区别,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。

server.listen(0)
  .then(function () {
    // run test
  })
  .finally(server.stop);

参考:http://es6.ruanyifeng.com/#docs/promisehttp://liubin.org/promises-book/、[MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise)

Last updated