promise如何使用?一文带你深入学习
resolve与rejected
在通过new创建一个Promise时,我们需要传入一个回调函数,称之为executor
executor会被立即执行,并且传入给resolve、reject
-
当我们调用resolve回调函数时,会执行Promise对象的then方法传入的回调函数
-
当我们调用reject回调函数时,会执行Promise对象的catch方法传入的回调函数
下面请看代码示例
const promise = new Promise((resolve, rejected) => {
//调用resolve会执行then传入的回调函数
resolve("aaaaa")
//调用rejected会执行catch传入的回调函数
// rejected("错误信息")
}
)
promise.then(res => {
console.log(`res:${res}`)
})
// promise.catch(res => {
// console.log(`res:${res}`)
// })
promise的状态
上面Promise使用过程,我们可以将它划分成三个状态
-
pending: 初始状态,既没有被兑现,也没有被拒绝; 当执行executor中的代码时,处于该状态
-
fulfilled: 意味着操作成功完成;执行了resolve时,处于该状态;
-
rejected: 意味着操作失败; 执行了reject时,处于该状态;
注意:一旦状态被确定下来,Promise的状态会被锁死,不能够再改变
调用resolve的时,如果resolve传入的值本身不是一个Promise,那么会将该Promise的状态变成fulfilled,后边我们去调用reject时,已经不会有任何的响应了(并不是这行代码不会执行,而是无法改变Promise状 态)
可以copy上面代码去掉注释试验一下。
resolve不同值的区别
(1)resolve传入一个普通的值或者对象,那么这个值会作为then回调的参数
const promise = new Promise((resolve, rejected) => {
resolve("normal resolve")
})
promise.then(res=>{
console.log(res)//normal resolve
})
(2)resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态
const promise = new Promise((resolve, rejected) => {
resolve(new Promise((resolve,rejected)=>{
resolve("第二层promise的resolve")
}))
})
promise.then(res=>{
console.log(res)//第二层promise的resolve
})
const promise = new Promise((resolve, rejected) => {
resolve(new Promise((resolve,rejected)=>{
rejected("第二层promise的rejected")
}))
})
promise.then(res=>{
console.log(res)
}).catch(error=>{
console.log(error)//第二层promise的rejected
})
(3)如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,并且根据 then 方法的结果来决定Promise的状态
const promise = new Promise((resolve, rejected) => {
resolve({
then:function(resolve,rejected){
resolve("执行then方法的resolve")
}
})
})
promise.then(res => {
console.log(`res:${res}`)//res:执行then方法的resolve
}).catch(error=>{
console.log(`error:${error}`)
})
const promise = new Promise((resolve, rejected) => {
resolve({
then:function(resolve,rejected){
rejected('执行then方法的reject')
}
})
})
promise.then(res => {
console.log(`res:${res}`)
}).catch(error=>{
console.log(`error:${error}`)// error:执行then方法的reject
})
rejected
const promise = new Promise((resolve, rejected) => {
rejected(new Promise((resolve,rejected)=>{
resolve("reject传入promise对象的resolve")
}))
})
promise.then(res=>{
console.log(res)
}).catch(error=>{
console.log(`error:${error}`)//error:[object Promise]
})
then方法
### 接收两个参数
then方法是Promise对象上的一个方法:它其实是放在Promise的原型上的 Promise.prototype.then
then方法接受两个参数: fulfilled的回调函数:当状态变成fulfilled时会回调的函数;
reject的回调函数:当状态变成reject时会回调的函数(在catch方法没出现之前,调用rejected会执行then传入的第二个回调函数)
catch
finally方法
-
finally是在ES9(ES2018)中新增的一个特性:表示无论Promise对象无论变成fulfilled还是reject状态,最终都会 被执行的代码
-
finally方法是不接收参数的,因为无论前面是fulfilled状态,还是reject状态,它都会执行
resolve方法
前面学习的then,catch,finally方法都属于Promise的实例方法,都是存在promise的原型上,
下面我们学习一下Promise的类方法。
- Promise.resolve的用法相当于new Promise,并且执行resolve操作
const data = Promise.resolve({name:"why"})
//等价于
//const data = new Promise((resolve)=>{
// resolve("111111111")
// })
data.then(res=>{
console.log(res)
})
-
resolve参数的形态:
情况一:参数是一个普通的值或者对象
情况二:参数本身是Promise
情况三:参数是一个thenable
// 类方法Promise.resolve // 1.普通的值 const data = Promise.resolve({name:"why"}) //等价于 //const data = new Promise((resolve)=>{ // resolve({name:"why"}) // }) data.then(res => { console.log(res)//name: "why" }) // 2.传入Promise const promise = Promise.resolve(new Promise((resolve, reject) => { resolve("11111") })) promise.then(res => { console.log("res:", res)//11111 }) // 3.传入thenable对象
reject方法
reject方法类似于resolve方法,只是会将Promise对象的状态设置为reject状态
Promise.reject的用法相当于new Promise,只是会调用reject
Promise.reject的用法相当于new Promise,只是会调用reject
all方法与race方法的区别
all方法
作用是将多个Promise包裹在一起形成一个新的Promise,期待所有的Promise都变成fulfilled后,把所有Promise的结果以数组的形式返回,需要注意的是,当有一个Promis状态为reject时,那么整个promise是rejected,新的promise状态为reject,并且会将第一个reject的返回值作为参数交给catch方法执行。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1111")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("222")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000)
})
Promise.all([p1, p2, p3]).then((res) => {
console.log(res)//['1111', '222', '333']
}).catch((err) => {
console.log(err)
})
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1111")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("错误信息")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("222")
}, 3000)
})
Promise.all([p1, p2, p3]).then((res) => {
console.log(res)
}).catch((err) => {
console.log(err)//错误信息
})
race方法
先到先得的原则,多个Promise只要有一个Promise变成fulfilled状态,那么就结束,如果在这之前有Promise已经是reject那么整个promise是rejected,将第一个reject的返回值作为参数交给catch方法执行。
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1111")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("222")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("333")
}, 3000)
})
Promise.race([p1,p2,p3]).then((res)=>{
console.log(res)//1111
}).catch((err)=>{
console.log(err)
})
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1111")
}, 2000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("错误信息")
}, 1000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("222")
}, 3000)
})
Promise.race([p1,p2,p3]).then((res)=>{
console.log(res)
}).catch((err)=>{
console.log(err)//错误信息
})
allSettled
上面的all方法,显然是有很大的缺陷,但其中一个Promise是reject的时候,新的Promise会变成rejected,那么对于resolve的,以及依然处于pending的Promise,我们是获取不到对应的结果。
ES11(ES2020)中,添加了新的API Promise.allSettled
-
该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是reject时,才会有最终的状态
-
并且这个Promise的结果一定是fulfilled的
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(11111)
}, 1000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22222)
}, 2000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(33333)
}, 3000);
})
Promise.allSettled([p1, p2, p3, "aaa"]).then(res => {
console.log(res)//输出结果如下:
// 0: {status: 'fulfilled', value: 11111}
// 1: {status: 'rejected', reason: 22222}
// 2: {status: 'fulfilled', value: 33333}
// 3: {status: 'fulfilled', value: 'aaa'}
}).catch(err => {
console.log(err)
})
any方法
any方法是ES12中新增的方法,和race方法是类似的
不过any方法会等到一个fulfilled状态,才会决定新Promise的状态
如果所有的Promise都是reject,那么也会等到所有的Promise都变成 rejected状态,并且报一个AggregateError的错误。
// 创建多个Promise
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1111")
}, 2000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("错误信息")
}, 1000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("33333")
}, 3000);
})
Promise.any([p1,p2,p3]).then(res=>{
console.log(res)//1111
}).catch((err)=>{
console.log(err)
})
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("1111")
}, 2000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("错误信息")
}, 1000);
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("33333")
}, 3000);
})
Promise.any([p1,p2,p3]).then(res=>{
console.log(res)
}).catch((err)=>{
console.log(err)//AggregateError: All promises were rejected
})