Promise是异步编程的一种解决方案,它有三种状态,分别是
pending-进行中
resolved-已完成
rejected-已失败
当Promise的状态由pending 转变为resolved或rejected时,会执行相应的方法,并且状态一旦改变,就无法再次改变状态,这也是它名字promise承诺的由来。
Promise的作用
一个Promise对象可以理解为一次将要执行的操作(常常被用于异步操作),使用了Promise对象之后可以用一种链式调用的方式来组织代码,让代码更加直观。
Promise对象有以下两个特点。
(1)对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。这也是Promise这个名字的由来,它的英语意思就是“承诺”,表示其他手段无法改变。
(2)一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。如果改变已经发生了,你再对Promise对象添加回调函数,也会立即得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
then
function printHello (ready) {
return new Promise(function (resolve, reject) {
if (ready) {
resolve("Hello");
} else {
reject("Good bye!");
}
});
}
function printWorld () {
alert("World");
}
function printExclamation () {
alert("!");
}
printHello(true)
.then(function(message){
alert(message);
})
.then(printWorld)
.then(printExclamation);
上述例子通过链式调用的方式,按顺序打印出了相应的内容。then可以使用链式调用的写法原因在于,每一次执行该方法总是会返回一个Promise对象。另外,在then onFulfilled的函数当中的返回值,可以作为后续操作的参数,因此上面的例子也可以写成
printHello(true).then(function (message) {
return message;
}).then(function (message) {
return message + ' World';
}).then(function (message) {
return message + '!';
}).then(function (message) {
alert(message);
});
catch
.catch()的作用是捕获Promise的错误,与then()的rejected回调作用几乎一致。但是由于Promise的抛错具有冒泡性质,能够不断传递,这样就能够在下一个catch()中统一处理这些错误。同时catch()也能够捕获then()中抛出的错误,所以建议不要使用then()的rejected回调,而是统一使用catch()来处理错误
Promise.all
Promise.all可以接收一个元素为Promise对象的数组作为参数,当这个数组里面所有的Promise对象都变味resolve时,该方法才会返回。
function p1(ready){
return new Promise(function(resolve,reject){
if(ready){
setTimeout(function () {
resolve("Hello");
}, 3000);
}
})
}
function p2(ready){
return new Promise(function(resolve,reject){
if(ready){
setTimeout(function () {
resolve("World");
}, 1000);
}
})
}
Promise.all([p1(true), p2(true)]).then(function (result) {
console.log(result); // ["Hello", "World"]
});
上面的例子模拟了传输两个需要数据不同的市场,虽然p2的速度比p1要快,但是Promise.all方法会按照数组里面的顺序将结果返回 日常开发中经常会遇到这样的需求,在不同的接口请求数据然后拼合成自己所需的数据,通常这些接口之间没有关联 例如不需要前一个接口的数据作为后一个接口的参数,这个时候Promise.all方法就可以派上用场了。
Promise.race
同样接受一个数组,武罗这个数组的状态是rosolve合适reject,该方法都会返回 返回的值取决于第一个promise为resolve的值,如果都为resolve,只返回第一个resolve的值
Promise.race([p1(false), p2(true)]).then(function (result) {
console.log(result); // ["Hello", "World"]
});