前言
Promise 想必大家都十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?下面通过几道题理解Promise的作用。
一、Promise的立即执行性
let p=new Promise((resolve,reject)=>{
console.log("1");
resolve("2");
console.log("3");
});
console.log("4");
p.then((value)=>{
console.log(value);
})
console.log(5)
// 1
// 3
// 4
// 5
// 2
Promise对象表示未来某个将要发生的事件,但在创建(new)Promise时,作为Promise参数传入的函数是会被立即执行的,只是其中作为参数中的两个函数执行的代码是异步代码。有些同学会认为,当Promise对象调用then方法时,Promise接收的函数才会执行,这是错误的,而是在then调用的时候,传入的函数中的参数函数才被执行,也就是resolve和reject才被执行。
二、Promise 三种状态
let p1=new Promise((resolve,reject)=>{
resolve(1);
})
let p2=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(2);
},500);
})
let p3=new Promise((resolve,reject)=>{
setTimeout(()=>{
reject(3);
},500);
})
console.log(p1);//Promise { 1 }
console.log(p2);//Promise { <pending> }
console.log(p3);//Promise { <pending> }
setTimeout(function(){
console.log(p2);
}, 1000);//Promise { <resolved> 2 }
setTimeout(function(){
console.log(p3);
}, 1000);//Promise { <rejected> 3 }
p1.then(function(value){
console.log(value);
});//1
p2.then(function(value){
console.log(value);
});//2
p3.catch(function(err){
console.log(err);
});//3
控制台分别输出:
Promise { 1 }
Promise { <pending> }
Promise { <pending> }
1
2
3
Promise { <resolved> 2 }
Promise { <rejected> 3 }
Promise的内部实现是一个状态机。Promise有三种状态:pending,resolved,rejected。当Promise刚创建完成时,处于pending状态;当Promise中的函数参数执行了resolve后,Promise由pending状态变成resolved状态;如果在Promise的函数参数中执行的不是resolve方法,而是reject方法,那么Promise会由pending状态变成rejected状态。
三、Promise 状态的不可逆性
let p1=new Promise((resolve,reject)=>{
resolve("p1成功");
resolve("p1又成功");
});
let p2=new Promise((resolve,reject)=>{
resolve("p2成功");
reject("reject");
});
p1.then((value)=>{
console.log(value);
})
p2.then((value)=>{
console.log(value);
})
状态栏输出:
p1成功
p2成功
Promise状态的一旦变成resolved或rejected时,Promise的状态和值就固定下来了,不论你后续再怎么调用resolve或reject方法,都不能改变它的状态和值。
四、链式调用
Promise.resolve(1)
.then((res)=>{
console.log(res);
return 2
})
.then((res)=>{
console.log(res);
return Promise.resolve(3)
})
.then((res)=>{
console.log(res);
})
.catch((err)=>{
console.log(err);
return 4
})
//1
//2
//3
promise 可以链式调用。promise 每次调用 .then 或者 .catch 都会返回一个新的 promise,从而实现了链式调用。其中return有以下三种情况:
- return 一个同步的值 ,或者 undefined(当没有返回一个有效值时,默认返回undefined),then方法将返回一个resolved状态的Promise对象,Promise对象的值就是这个返回值。
- return 另一个 Promise,then方法将根据这个Promise的状态和值创建一个新的Promise对象返回。
- throw 一个同步异常,then方法将返回一个rejected状态的Promise, 值是该异常。
五、Promise then() 回调异步性
var p = new Promise((resolve, reject)=> {
setTimeout(()=>{
console.log("1");
resolve("success");
},1000)
});
p.then(function (value) {
console.log(value);
});
p.then(function (value) {
console.log(value);
});
//1
//success
//success
Promise接收的函数参数是同步执行的,但then方法中的回调函数执行则是异步的,因此,"success"会在后面输出。
六、异常
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
.then 或者 .catch 中 return 一个 error 对象并不会抛出错误,所以不会被后续的 .catch 捕获。
七、值穿透
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
//1
.then 或者 .catch 的参数期望是函数,传入非函数则会发生值穿透。
网友评论