Promise对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。

它的一般表现形式为

1
2
3
4
5
6
7
new Promise(function(resolve,reject){
if(/*success*/){
resolve();
}else{ /*fail*/
reject();
}
});

Promise对象的特点

Promise对象具有以下两个特点:

  1. 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是”承诺”,表示其他手段无法改变。

  2. 一旦状态改变,就不会再变,任何时候的可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,这时就成为resolved(已定型)。如果该改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。

Promise对象的方法

Promise.prototype.then()

Promise对象含有then方法,then()调用后返回一个Promise对象,意味着实例化后的Promise可以进行链式调用,而且这个then()方法可以接收两个函数,一个是
处理成功后的函数,一个是处理错误的函数。
如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
let promise = new Promise(function(resolve,reject){
//2s后设置为接收状态
setTimeout(resolve,2000,'success')
})
promise.then(function(data){
console.log(data) //success
return data
},function(err){
console.log(err)
}).then(function(data){
//上一步的then()方法的返回值
console.log('链式调用'+data); //链式调用success
},function(data){
//...
})

Promise.prototype.catch()

catch()方法和then()状态一样,都会放回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:

1
2
3
4
5
6
7
8
9
10
11
let promise = new Promise(function(resolve,reject){
setTimeout(reject,2000,'fail')
})
promise
.then(function(data){
console.log(data)
return data
})
.catch(function(err){
console.log(new Error('出错:',err)); //Error:出错
})

Promise.all()

Promise.all()接收一个参数,它必须是可以迭代的,比如数组。

它通常用来处理一些并发的异步操作,即他们的结果互不打扰,但是有需要异步执行。它最终只有两种状态:成功或者失败。

它的状态受参数内各个之的状态影响,即里面状态全部为fulfilled时,它才会变为fulfilled,否则变成rejected

成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:

1
2
3
4
5
6
7
8
9
10
11
12
//fulfilled状态的情况
var arr = [1,2,3]
var promise = arr.map(function(e){
return new Promise(function(resolve,reject){
resolve(e * 5)
});
});

Promise.all(promise).then(function(data){
console.log(data) //[5,10,15]
console.log(arr) //[1,2,3]
// })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//rejected状态的情况
var arr = [1,2,3]
var promise2 = arr.map(function(e){
return new Promise(function(resolve,reject){
if(e==2){
reject('rejected')
}
resolve(e * 5)
});
});

Promise.all(promise2).then(function(data){
//这里不执行
console.log(data)
console.log(arr)
}).catch(function(err){
console.log(Error('错误'+err)) //Error:错误rejected
})

Promise.race()

Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生了改变,那么该Promise的状态就是改变的状态。就跟race的字面意思一样,谁跑的快谁赢。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var p1 = new Promise(function(resolve,reject){
setTimeout(resolve,300,'p1 done')
})
var p2 = new Promise(function(resolve,reject){
setTimeout(resolve,50,'p2 done')
})
var p3 = new Promise(function(resolve,reject){
setTimeout(reject,100,'p3 reejcted')
})

Promise.race([p1,p2,p3]).then(function(data){
//显然p2更快,所以状态变成了fulfilled
//如果p3更快,那么状态就会变成rejected
console.log(data) //p2 done
}).catch(function(err){
console.log(err)
});

Promise.resolve()

Promise.resolve()接受一个参数值,可以是普通的值具有then()方法的对象Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析发生错误时,返回Promise对象将会置为rejected态。如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

//参数为普通值
var p4 = Promise.resolve(5);
p4.then(function(data){
console.log(data) //5
});

//参数为含有then()方法的对象
var obj = {
then:function(){
console.log('obj 里面的then()方法')
}
};
var p5 = Promise.resolve(obj);
p5.then(function(data){
console.log(data) //obj 里面的then()方法
});

//参数为Promise实例
var p6 = Promise.resolve(6)

var p7 = Promise.resolve(p6)
p7.then(function(data){
console.log(data) //6
})

//参数为Promise实例,但是参数是reject状态
var p8 = Promise.reject(8)

var p9 = Promise.resolve(p8)
p9.then(function(data){
console.log(data) //不执行
}).catch(function(err){
console.log(new Error("错误:"+err)) //Error:错误:8
})

Promise.reject()

Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:

1
2
3
4
5
6
7
8
var p10 = Promise.reject('手动拒绝');
p10.then(function(data){
console.log(data) //不执行
}).catch(function(err){
console.log(new Error("错误:"+err)) //Error:错误:手动拒绝
}).then(function(data){
console.log('状态:fulfilled'); //状态:fulfilled
})

总之,除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态影响。

参考: