一丶什么是Promise对象?
1.Promise对象是用于解决异步编程的一种方案,解决回调地狱问题的。
2.Promise对象有三种状态pending(进行中),fullfiled(已成功),rejected(已失败)
3.Promise的状态一旦从pending改为fullfiled或者rejected就不会在改变。
示意图:
Promise接收一个回调函数,回调函数,两个参数resolve和reject都是函数。resolve调用promise实例的状态为fullfiled,reject调用promise实例的状态为rejected
// Promise接收一个回调函数,回调函数里两个参数resolve和reject
let promise = new Promise((resolve,reject)=>{
resolve() // resolve调用生成的promise实例的状态为fullfiled
reject()
})
// promise实例的状态为fullfiled,因为状态一旦改边变就不会再变
console.log(promise)
resolve或者reject接收的参数作为promise实例对象里携带的数据
let promise = new Promise((resolve,reject)=>{
reject("promise实例携带的数据") // reject调用生成的promise实例状态为rejected
})
// promise实例的状态为rejected
console.log(promise)
二丶Promise对象实例的方法
1.then
then
方法的第一个参数是resolved
状态的回调函数,第二个参数(可选)是rejected
状态的回调函数。而在回调函数中的参数是resolve(或者reject)调用的时候传的实参(携带的数据),回调函数在promise状态改变时调用,fullfiled状态调用第一个,rejected状态调用第二个
then
方法返回的是一个新的Promise
实例(注意,不是原来那个Promise
实例)。因此可以采用链式写法,即then
方法后面再调用另一个then
方法。
let promise = new Promise((resolve,reject)=>{
resolve('data')
})
let promise1 = promise.then(res=>{
console.log(res) // data
return 'aaa'
})
// .then调用之后返回了一个新的promise对象,携带的数据为.then回调函数返回的数据
console.log(promise1)
2.catch
catch方法是.then(null,rejection)或者.then(undefined,rejection)的别名。接收一个回调函数,该回调函数在promise对象状态为rejected或者当前面的.then里的回调函数执行出错的时候调用。会捕获到.then里抛出的错误。
let promise = new Promise((resolve,reject)=>{
reject('666')
}).then(res=>{
// 不执行
console.log(res)
}).catch(err=>{
console.log(err) // 666
return 'data'
})
console.log(promise)
需要注意的是:当promise实例自己定义了.catch方法捕获了抛出的错误则返回的新promise对象的状态是fullfiled。
let promise = new Promise((resolve,reject)=>{
resolve('test')
}).then(res=>{
// 这里在a的暂时性死区使用a会抛出错误
console.log(a)
let a = 5
console.log(res)
}).catch(err=>{
// 这里会捕获到.then中抛出的错误
console.log(err)
})
console.log(promise)
3.finally
.finally方法回调不接收任何参数,不管promise对象的状态是什么都会执行回调。执行finally方法后不影响promise所携带的数据。还是会携带之前的数据。
let promise = new Promise((resolve,reject)=>{
resolve('test')
}).then(res=>{
console.log(a)
let a = 5
console.log(res)
}).catch(err=>{
console.log(err)
return 'catch'
}).finally(()=>{
console.log('finally')
return new Promise(resolve=>{
resolve('111')
})
})
console.log(promise)
三丶Promise的静态方法
1.Promise.resolve
(1)当Promise.resolve的参数是一个promise对象时,Promise.resolve方法会原封不动的返回这个promise对象。
(2)当参数是一个thenable对象的话,Promise.resolve会先把这个thenable对象转为promise对象再执行里面的then方法,如果then方法里resolve执行则Promise.resolve返回fullfiled状态的promise实例,如果reject执行则Promise.resolve返回一个rejected状态的promise实例。
// thenable对象
let thenable={
then:(resolve,reject)=>{
reject(333)
}
}
let p = Promise.resolve(thenable)
console.log(p)
(3)当Promise.resolve的参数是一个普通的原始值时。Promise.resolve返回一个fullfilled状态的promise对象。
let p = Promise.resolve('hello')
console.log(p)
(4)不传参数时返回一个Promise.resolve返回一个fullfiled状态的promise实例,携带的数据为undefined(不携带数据)
2.Promise.reject
Promise.reject(reason)会返回一个promise实例状态为rejected。
注意:Promise.reject(reason)的参数会原封不动的作为rejected的理由。
let p = Promise.resolve('hello')
let promise = Promise.reject(p)
console.log(promise)
promise.catch(err=>{
console.log(err===p) // true
})
3.Promise.all
Promise.all()将多个promise实例包装成一个新的promise实例。参数接收一个数组,或者是具有Iterator接口的。如果数组中的元素不是promise实例,则会先调用Promise.resolve()之后再进一步处理。
由Promise.all([p1,p2,p3])方法返回的新的promise对象的状态由参数的每个元素所决定。
(1)当p1,p2,p3的状态都为fullfiled时返回的新promise对象的状态才是fullfiled。而p1,p2,p3的返回值组成一个数组。
let p1 = Promise.resolve('p1')
let p2 = Promise.resolve('p2')
let p3 = new Promise(resolve=>{
setTimeout(()=>{
resolve("p3")
},2000)
})
let p = Promise.all([p1,p2,p3])
console.log(p)
setTimeout(()=>{
console.log(p)
},3000)
当p3的状态未变为fullfiled时,p的状态是pending状态。当p1,p2,p3都为fullfiled时,p的状态才变为fullfiled而p1,p2,p3携带的数据会组成一个数组成为p所携带的数据。
(2) 当p1,p2,p3中有一个为rejected状态p的状态就为rejected,状态最先变为rejected携带的数据,传递给p,作为p携带的数据。
let p1 = Promise.resolve('p1')
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p2")
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p3")
}, 3000)
})
let p = Promise.all([p1, p2, p3])
console.log(p)
setTimeout(() => {
console.log(p)
}, 4000)
需要注意的是:如果作为参数的promise实例定义了catch方法的话,如果被rejected的话会触发自己的catch,Promise.all()的catch不会触发。
4.Promise.race
Promise.race()方法的参数和Promise.all()方法一样,接收一个数组或是具有Iterator接口。数组中如果不是promise对象会调用Promise.resolve()先处理成promise对象再进一步处理。
参数中谁率先得到结果,Promise.race()的状态就和最新得到结果的promise实例一致,携带的数据也是最快得到结果的promise实例传递的数据。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p1")
}, 1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p2")
}, 2000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p3")
}, 3000)
})
let p = Promise.race([p1, p2, p3])
console.log(p)
5.Promise.any
Promise.any()方法接收一组promise实例为参数。包装成新的promise实例。只要参数中有一个变为fullfiled,新的promise实例的状态就为fullfiled。全部都为rejected时,新的promise对象的状态才会变成rejected。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p1")
}, 2000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("p2")
}, 3000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("p3")
}, 4000)
})
let p = Promise.any([p1, p2, p3])
console.log(p)
setTimeout(() => {
console.log(p)
}, 5000)
6.Promise.allSettled
Promise.allSettled()方法接收一组promise实例作为参数。包装成一个新的promise实例。只有等参数里的所有实例都返回结果之后欧,才会包装结束。结束后包装成的promise实例的状态总是fullfiled状态。
const resolved = Promise.resolve(42);
const rejected = Promise.reject(-1);
const allSettledPromise = Promise.allSettled([resolved, rejected])
console.log(allSettledPromise)
allSettledPromise.then(function (results) {
console.log(results)
})