Promise对象笔记

177 阅读3分钟

Promise的特点:

  1. 对象代表一个异步操作,有3种状态: Pending,Resolved(Fulfilled)和Rejected。
  2. 一旦状态改变就不会再变,任何时候都可以得到结果。

Promise的缺点

  1. 无法取消Promise,一旦新建就会立即执行,中途无法取消。
  2. 如果不设置回调函数,Promise内部抛出的错误不会反应到外部。
  3. 处于Pending状态时,无法得知目前进行到哪一阶段。

Promise基本用法

function timeout(ms) {
    return new Promise((resolve, reject) => {
        setTimeout(resolve, ms, 'done');
    });
} 

timeout(100).then(value => { console.log(value); }, error => {console.error(error)} );

then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为Resolved时调用, 第二个回调函数是Promise对象的状态变为Rejected时调用。其中,第二个函数是可选的,不建议提供(后面会讲到catch()

下面是一个异步加载图片的例子

function loadImageAsync(url) {
    return new Promise(function(resolve, reject) {
        var image = new Image();
        
        image.onload = function() {
            resolve(image);
        };
        
        image.onerror = function() {
            reject(new Error('Could not load image at ' + url));
        };
        
        image.src = url;
    });
}

如果调用resolve函数或者reject函数时带有参数,那么这些参数会被传递给回调函数函数。reject函数的参数通常是Error对象的实例,表示抛出的错误; resolve函数的参数除了正常值,也可以是另外一个一步操作。

var p1 = new Promise(function(resolve, reject) {
    setTimeout(() => reject(new Error('fail')), 3000);
});
var p2 = new Promise(function(resolve, reject) { 
    setTimeout(() => resolve(p1), 1000); 
});
p2.then(result => console.log(result));
p2.catch(error => console.log(error));

p1是一个promise,3秒变成Rejected。p2的状态由p1决定,1秒之后,p2调用resolve方法,此时p1的状态还没改变,p2的状态也不会变。又过了2秒,p1变为Rejected,p2也跟着变为Rejected。

Promise.prototype.then()

Promise实例具有then方法,then方法定义在原型对象上的。作用是为Promise实例添加状态改变时的回调函数。then的方法返回一个心的Promise实例,因为可以使用链式写法。 p1.then(value1 => (value1)).then(value2 => (value2))

Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection)的别名,用于指定发生错误时的回调函数。前面提过.then(func1,func2)的func2是用来捕获错误的,推荐使用catch。 promise.then(function(data) {}).catch(function(error) {});

Promise.all()

var p = Promise.all([p1, p2, p3]); Promise.all方法的参数不一定是数组,但是必须有Iterator接口,返回的每个成员都是Promise实例。p的状态由p1,p2,p3决定,分两种情况

  1. 3个状态都成了Fulfilled, p的状态才会变成Fulfilled, 此时p1,p2,p3的返回值组成一个数组,传递给p的回调函数。
  2. 只要有一个被Rejected,p的状态就是Rejected,第一个被Rejected的实例返回值传递给p的回调函数。

Promise.race()

var p = Promise.race([p1, p2, p3]); 只要有一个实例率先改变状态,p的状态就会跟着改变。率先返回的值就传给p的回调函数。

Promise.resolve() Promise.reject()

将现有的对象转换成Promise对象,回调函数会立即执行。

done()

最后一个方法抛出的错误可能无法捕捉到,可以提供done方法在回调链的尾端。 asyncFunc().then(f1).catch(r1).then(f2).done(); done可以像then方法那样,提供Fulfilled和Rejected状态的回调函数。

finally()

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