Promise学习记录
什么是Promise
Promise是一个类,意思为承诺、许诺、期约;
当我们需要的时候,给与调用者一个承诺,等会我会给你回调数据时,就可以创建一个Promise对象;
在通过New创建Promise对象时,我们需要传入一个回调函数,我们称之为Executor
- 这个回调函数会被立即执行,并且传入另外两个回调函数 resolve and reject;
- 当我们调用resolve回调函数是,会执行Promise对象的then方法传入的回调函数
- 当我们调用reject回调函数是,会执行Promise对象的catch方法传入的回调函数
Promise的状态:
-
待定(pending) : 初始状态,既没有对线,也没有被拒绝;
当执行exector的代码是,处于该状态
-
已兑现(fulfilled) : 意味着操作完成;
执行了resolve时,处于该状态,Promise 已经被兑现;
-
已拒绝(rejected) : 意味着操作失败;
执行了reject时,处于该状态,Promise已经被拒绝;
const promise = new Promise((resolve, reject) => {
resolve("成功")
reject("拒绝")
})
promise.then(res => {
console.log(res)
}).catch((err) => {
console.log(err)
})
注:Promise状态一旦变更无法更改,在我们调用resolve的时候,如果resolve传入的值本身不是一个Promise,那么该Promise的状态变成兑现,在之后去调用reject时,已经不会有任何的响应了
resolve 不同值的区别
- 如果resolve传入的是一个普通的值或者对象,那么这个值会做为then回调参数;
- 如果resolve传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态
- 如果resolve传入的是一个对象,并且这个对象有实现then方法,那么会执行then方法,并且根据then方法的结果来决定Promise的状态
const promise = new Promise((resolve, reject) => {
resolve("成功")
})
promise.then(res => {
console.log(res) //成功
}).catch((err) => {
console.log(err)
})
const promise = new Promise((resolve, reject) => {
resolve(new Promise((resolve, reject) => {
setTimeout(()=>{
resolve("第二个Promise的resolve")
})
}))
})
promise.then(res => {
console.log(res) //第二个Promise的resolve
}).catch((err) => {
console.log(err)
})
const promise = new Promise((resolve, reject) => {
resolve({
then:function (re, rj){
re("我是带有then方法的对象")
}
})
})
promise.then(res => {
console.log(res) //我是带有then方法的对象
}).catch((err) => {
console.log(err)
})
then方法-接收两个参数
- then方法是Promise对象上的一个方法(实例方法):
其实是放在Promise原型上的Promise.prototype.then
-
then方法接收两个参数
- fullfield的回调函数,当状态变成fulfilled时会回调的函数;
- reject的回调函数,当状态变成reject时会回调的函数;
console.log( Promise.prototype.then) //[Function: then]
promise.then(res => {
console.log(res) //我是带有then方法的对象
}).catch((err) => {
console.log(err)
})
//=================两者等价
promise.then(res => {
console.log(res) //我是带有then方法的对象
},(err) => {
console.log(err)
})
then方法-返回值
then方法的返回值是一个Promise,所以可以进行链式调用
Promise有三种状态,那么这个Promise处于什么状态呢?
? 当then方法中的回调函数本身在执行的时候,那么它处于pending状态
-
当then方法中的回调函数返回一个结果时,那么它处于fulfilled状态,并且会将结果作为resolve的参数;
✓ 情况一:返回一个普通的值;
✓ 情况二:返回一个Promise;
✓ 情况三:返回一个thenable值;
-
当then方法抛出一个异常时,那么它处于reject状态;
catch方法
- catch方法是Promise对象上的一个方法(实例方法):
其实是放在Promise原型上的Promise.prototype.catch
catch方法-返回值
catch方法的返回值也是一个Promise对象,所以catch方法后面我们可以继续调用then方法或者catch方法“
const promise = new Promise((resolve, reject) => {
reject("拒绝")
})
promise.then(res => {
console.log(res)
}).catch((err) => {
console.log(err)//拒绝
}).then(res => {
console.log("catch后面的then", res)// catch后面的then undefined
})
/* 运行结果:拒绝
catch后面的then undefined
*/
注意:catch传入的回调在执行完后,默认状态依旧会是已兑现状态
如果我们希望后续继续执行catch,那么需要抛出一个异常:
const promise = new Promise((resolve, reject) => {
reject("拒绝")
})
promise.then(res => {
console.log(res)
}).catch((err) => {
console.log(err)//拒绝
throw new Error("reject")
}).then(res => {
console.log("catch后面的then", res)
}).catch(err=>{
console.log("第二次catch", err.message)//第二次catch reject
})
/*运行结果
拒绝
第二次catch reject
*/
Promise其他方法
Finally 方法
- finally实在ES9(ES2018)中新增的一个特性,表示无论Promise对象无论变成fulfilled还是rejected状态,最终都会执行代码
- finally方法不接收参数,因为无论前面试fulfilled状态还是reject的状态,他都会执行
const promise = new Promise((resolve, reject) => {
// resolve("成功")
reject("拒绝")
})
promise.then(res => {
console.log(res)
}).catch((err) => {
console.log(err)//执行
}).finally(() => {
console.log("finally函数")//执行
})
resolve方法
then、catch、finally方法都属于Promise的实例方法,都是存放在Promise的Prototype上
resolve是一个类方法
参数形态
- 普通的值或者对象
- 本身是Promise
- 参数是一个对象且有then函数
Promise.resolve("mjy").then(res=>{
console.log(res)
})
//等价于
new Promise((resolve) => resolve("mjy"))
相当于new Promise,并且执行resolve
reject方法
reject方法类似于类方法resolve,只是会将Promise对象的状态设置为reject状态
Promise.rejec用法相当于new Promise,只是会调用reject
参数形态
- 无论参数是什么祥泰,都会直接做为reject状态的参数传递到catch
Promise.resolve("mjy").then(res=>{
console.log(res)
})
//等价于
new Promise((resolve,reject) => reject("mjy"))
相当于new Promise,并且执行reject
All方法
作用:将多个Promise包裹在一起行成一个新的Promise对象;
新的Promise对象状态由包裹的所有Promise对象共同决定:
- 当所有的对象转态变化才能fulfilled状态时,新的Promise对象状为fulfilled,并且会将所有的Promise的返回值组成一个数组;
- 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;
- 传入一个可迭代对象
缺陷:dang 一个Promise变成rejected状态是,新的Promise就会立即变成对应的reject转态,
那么对于处于resolved的,以及依然处于pending状态的Promise,我们是获取不到对应结果的
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("拒绝")//返回
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功")
}, 3000)
})
Promise.all([p1,p2,p3]).then(res => {
console.log(res)
}).catch((err) => {
console.log(err)
})
//执行结果 有reject 返回了 拒绝
//无reject 返回了 [ '成功', '成功', '成功' ]
allSettled方法
新增于ES11(ES2020)
- 该方法会在所有的Promise都有结果(settled),无论是fulfilled还是rejected,才会有最终的状态
- 这个Promise的结果一定是fulfilled
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("拒绝")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功")
}, 3000)
})
Promise.allSettled([p1,p2,p3]).then(res => {
console.log(res)
}).catch((err) => {
console.log(err)
})
/*执行结果
[
{ status: 'fulfilled', value: '成功' },
{ status: 'rejected', reason: '拒绝' },
{ status: 'fulfilled', value: '成功' }
]
*/
race方法
如果有一个Promise有了结果,我们就希望决定最终新Promise的状态,那么可以使用race方法
表示多个Promise相互竞争,谁先有结果,那么就使用谁得结果,无论fulfilled还是rejected
any方法
-
any方法是ES12中新增的方法
-
any方法会等到一个fulfilled状态,才会决定新Promise的状态
-
如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态
注意:如果所有的Promise都是rejected的,那么会报一个AggregateError错误
const p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("拒绝")
}, 1000)
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("拒绝")
}, 2000)
})
const p3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject("拒绝")
}, 3000)
})
Promise.any([p1,p2,p3]).then(res => {
console.log(res)
}).catch((err) => {
console.log(err)
})
/*
运行结果
[AggregateError: All promises were rejected] {
[errors]: [ '拒绝', '拒绝', '拒绝' ]
}
*/