Promise原理讲解 && 实现一个Promise对象 (遵循Promise/A+规范)
面试精选之Promise
搞懂这两篇文章就差不离了
Promise 的使用
promise是一个构造函数,new Promise()返回一个promise对象,构造方法接受一个excutor函数作为参数,
excutor函数包含resolve和reject两个参数
const promise = new Promise((resolve, reject) => {
// 异步处理
// 处理结束后、调用resolve 或 reject
});
Promise相当于一个状态机
有三种状态:
pending:promise对象初始化的状态
fulfilled:当调用resolve(成功),会由pending => fulfilled
rejected:当调用reject(失败),会由pending => rejected
promise对象方法
then
then方法注册 当resolve(成功)/reject(失败)的回调函数
// onFulfilled 是用来接收promise成功的值
// onRejected 是用来接收promise失败的原因
promise.then(onFulfilled, onRejected);
注意:then方法是异步执行的
resolve
resolve(成功) onFulfilled会被调用
const promise = new Promise((resolve, reject) => {
resolve('fulfilled'); // 状态由 pending => fulfilled
});
promise.then(result => { // onFulfilled
console.log(result); // 'fulfilled'
}, reason => { // onRejected 不会被调用
})
reject(失败) onRejected会被调用
const promise = new Promise((resolve, reject) => {
reject('rejected'); // 状态由 pending => rejected
});
promise.then(result => { // onFulfilled 不会被调用
}, reason => { // onRejected
console.log(reason); // 'rejected'
})
catch
在链式写法中可以捕获前面then中发送的异常,
promise.catch(onRejected)
相当于
promise.then(null, onRrejected);
// 注意
// onRejected 不能捕获当前onFulfilled中的异常
promise.then(onFulfilled, onRrejected);
// 可以写成:
promise.then(onFulfilled)
.catch(onRrejected);
promise chain
promise.then方法每次调用 都返回一个新的promise对象 所以可以链式写法
function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
var promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected) // 捕获前面then方法中的异常
/**
then 的方法异常 下面的方法不在执行 直接走catch
**/
function taskA() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
reject("Task A setTimeOut");
},2000)
})
}
function taskB(result) {
console.log("Task B",result);
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
var promise = Promise.resolve(111);
promise.then(async (result)=>{
console.log("Task A start");
await taskA()
console.log("Task A end");
})
.then(taskB)
.catch(onRejected) // 捕获前面then方法中的异常
function taskA() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("Task A setTimeOut");
},2000)
})
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
var promise = Promise.resolve(111);
promise.then(async (result)=>{
console.log("Task A start");
console.log(await taskA())
console.log("Task A end");
})
.then(taskB)
.catch(onRejected) // 捕获前面then方法中的异常
promise静态方法
Promise.resolve 返回一个fulfilled状态的promise对象
Promise.resolve('hello').then(function(value){
console.log(value);
});
Promise.resolve('hello');
// 相当于
const promise = new Promise(resolve => {
resolve('hello');
});
Promise.reject 返回一个rejected状态的promise对象
Promise.reject(24);
new Promise((resolve, reject) => {
reject(24);
});
Promise.all 接收一个promise对象数组为参数
只有全部为resolve才会调用 通常会用来处理 多个并行异步操作
值得注意的是,返回的数组结果顺序不会改变,即使P2的返回要比P1的返回快,顺序依然是P1,P2
const p1 = new Promise((resolve, reject) => {
resolve(1);
});
const p2 = new Promise((resolve, reject) => {
resolve(2);
});
const p3 = new Promise((resolve, reject) => {
resolve(3);
});
Promise.all([p1, p2, p3]).then(data => {
console.log(data); // [1, 2, 3] 结果顺序和promise实例数组顺序是一致的
}, err => {
console.log(err);
});
Promise.race 接收一个promise对象数组为参数
Promise.race 只要有一个promise对象进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败
一般用于和定时器绑定,比如将一个请求和一个三秒的定时器包装成Promise实例,加入到race队列中,请求三秒中还没有回应时,给用户一些提示或一些相应的操作
const p1 = new Promise((resolve, reject) => {
setTimeout(()=>{resolve("success")},1000)
});
const p2 = new Promise((resolve, reject) => {
setTimeout(()=>{reject("fail")},500)
});
Promise.race([p1,p2]).then((result)=>{
console.log(result)
}).catch((err)=>{
console.log(err)
})