Promise是什么
Promise对象用于异步操作,它表示尚未完成且预计在未来完成的异步操作。
可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果
Promise构造函数
const p=new Promise((resolve,reject)=>{
if(成功){
resolve('success')
}else{
reject('error')
}
})
构造函数传入一个函数,这个函数的两个参数(resolve,reject)是函数类型,由构造函数内部提供。
Promise实例有三种状态:pending、fulfilled 、rejected,状态只能由 Pending 变为 Fulfilled 或由 Pending 变为 Rejected ,且状态改变之后不会在发生变化,会一直保持这个状态
resolve和reject
- resolve函数:将当前Promise实例的状态由pending转为fulfilled(this.status=fulfilled)
- reject函数:将当前Promise实例的状态由pending转为rejected(this.status=rejected)
resolve函数传入的值
- 如果传入的值不属于Promise实例,则该值会作为成功的回调函数的参数(在then方法的参数指定了回调函数)
- 如果传入的是Promise实例p1,则当前Promise实例p2的状态由p1决定,则p2的回调函数会等待p1的状态改变才执行。
const p1 = new Promise(function (resolve, reject) {
// ...
});
const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1);
})
Promise的值
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('FULFILLED')
}, 1000)
})
这里resolve 传入的 "FULFILLED" 就是 Promise 的值
resolve 和 reject 都可以传入任意类型的值作为实参,表示 Promise 对象成功(Fulfilled)和失败(Rejected)的值
then函数
const p=new Promise((resolve,reject)=>{
if(成功){
resolve('success')
}else{
reject('error')
}
})
p.then(function(val){
console.log(val); //success
},function(err){
console.log(err); //error
})
参数可选
promise.then(onFulfilled, onRejected)
- 如果参数不是函数,则被忽略,会发生值穿透
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3)) //Promise.resolve(3)不是函数
.then(console.log)//console.log是一个函数。这个可以接收,所以结果是console.log(1).
运行结果:
1
- then函数的参数是两个回调函数,then函数内部通过this(当前Promise实例p)的状态status来决定调用哪一个回调。
-
- onFulfilled:其第一个参数为promise 成功状态传入的值( resolve 执行时传入的值,值保存在Promise实例上,因此可以访问)
- onRejected:其第一个参数为 promise 失败状态传入的值( reject 执行时传入的值)
返回值
- then函数返回的是一个新的Promise实例,所以then可以链式调用。
then函数可以多次调用
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('once')
resolve('success')
}, 1000)
})
const start = Date.now()
promise.then((res) => {
console.log(res, Date.now() - start)
})
promise.then((res) => {
console.log(res, Date.now() - start)
})
运行结果:
once
success 1005
success 1007
then函数返回的Promise实例的状态
返回的新的Promise实例的状态依赖于当前then方法的回调函数执行的情况及返回值
- 如果回调返回的是一个值,则将该值作为Promise实例的值,传入下一个then的回调函数的参数
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
})
promise2 = promise1.then(res => {
// 返回一个普通值
return '这里返回一个普通值'
})
promise2.then(res => {
console.log(res) //1秒后打印出:这里返回一个普通值
})
- 如果回调函数执行过程出错,则Promise实例的状态为rejected
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
promise2 = promise1.then(res => {
throw new Error('这里抛出一个异常e')
})
promise2.then(res => {
console.log(res)
}, err => {
console.log(err) //1秒后打印出:这里抛出一个异常e
})
- 如果回调函数返回了一个新的Promise实例p2,则当前Promise实例的状态由p2的状态决定,等到p2状态改变才会执行后续的回调。
let promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 1000)
})
promise2 = promise1.then(res => {
// 返回一个Promise对象
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('这里返回一个Promise')
}, 2000)
})
})
promise2.then(res => {
console.log(res) //3秒后打印出:这里返回一个Promise
})
- 如果返回的是一个Error对象
Promise.resolve()
.then(() => {
return new Error('error!!!')
})
.then((res) => {
console.log('then: ', res)
})
.catch((err) => {
console.log('catch: ', err)
})
运行结果:
then: Error: error!!!
at Promise.resolve.then (...)
at ...
解释:.then或.catch的参数--回调函数返回一个error对象并不会抛出错误,不会后续的.catch捕获到,如果改为throw new Error('error!!!')则会被catch捕获到。
Promise.resolve()
- 参数:普通值 / Promise对象 / thenable对象(即带有"then" 方法)
- 返回值:
- 当参数是一个普通值,返回一个resolved类型的Promise对象
- 当是Promise对象,则返回这个Promise对象
- 当是thenable对象,则返回的Promise对象会“跟随”这个thenable的对象,采用它的最终状态;
var p1 = Promise.resolve( 1 );
var p2 = Promise.resolve( p1 );
var p3 = new Promise(function(resolve, reject){
resolve(1);
});
var p4 = new Promise(function(resolve, reject){
resolve(p1);
});
console.log(p1 === p2);
console.log(p1 === p3);
console.log(p1 === p4);
console.log(p3 === p4);
p4.then(function(value){
console.log('p4=' + value);
});
p2.then(function(value){
console.log('p2=' + value);
})
p1.then(function(value){
console.log('p1=' + value);
})
作者:艾特老干部
链接:https://juejin.cn/post/6844903488695042062
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
输出:
true
false
false
false
p2=1
p1=1
p4=1
解析:
为什么p2的then比p1的先执行呢?因为p2的then写在前
为什么p4的then最后调用呢?因为resolve函数接收的是一个Promise对象,resolve会对该对象拆箱,获取p1的状态和值,是一个异步操作。