1.目标
理解promise的基础实现原理,并正确理解和使用Promise
2.实现简易版Promise
2.1理解Promise的功能
看一下Promise的使用
const a = new Promise((resolve,reject) => {});
a.then(a => {
console.log('a',a)
})
-
是一个可以new的函数(这里用es6的calss)
-
接受一个回调,有两个参数,resolve,reject;
调用resolve,定制想返回的内容,状态从pending ---> fulfilled
调用reject,定制返回的错误原因, 状态从pending ---> rejectd
-
立即执行
-
存在三种状态
状态: PENDING FULFILLED REJECTED
状态流转:
pending ---> fulfilled pending ---> rejected -
实例方法 5.1 then
-
实例方法,不是挂载prototype上的;
-
接受两个参数 onFulfilled onRejected;
-
5.2 resole
调用resolve,定制想返回的内容,状态从pending ---> fulfilled
5.3 reject
调用reject,定制返回的错误原因, 状态从pending ---> rejectd
2.2 实现构建初始MPromise类
-
构造类
-
类属性
value: 成功返回值(undefined,thenable,promise) reason: 错误返回值 status:状态 resolve:promise的回调第一个参数( 实例调用状态为fulfilled的成功方法) reject:promise的回调第二个参数(实例调用状态为fulfilled的失败方法) -
代码
const PENDING = 'PENDING'; const REJECTED = 'REJECTED'; const FULFILLED = 'FULFILLED'; class MPromise{ constructor(fn) { this.value = undefined; this.reason = undefined; this.status = PENDING; } resolve(newValue) { if(this.status === PENDING) { // 状态只能从一种状态变成另外一种,不可逆 this.status = FULFILLED; this.value = newValue; } } reject(newReason) { if(this.status === 'PENDING') { this.status = REJECTED; this.reason = newReason; } } } const testP = new MPromise((resolve,reject) => { }); console.log('testP',testP); // 状态为pending
2.3 实现promise 的立即执行
现在测试使用promise,按照promsi规范,Promise 规范会立即输出000,但是现在并没有输出。
问: 如何执行匿名函数(resolve,reject) => {}?
答:在类constructor 执行即可
const testP = new MPromise((resolve,reject) => {
console.log('000')
});
修改实现代码:
constructor(fn) {
this.value = undefined;
this.reason = undefined;
this.status = PENDING;
try { // try 防止报错
fn(this.resolve.bind(this),this.reject.bind(this));
} catch (error) {
this.reject(error)
}
}
测试执行:
const testP = new MPromise((resolve,reject) => {
console.log('000')
});
console.log('testP',testP); // 状态为pending
const testP = new MPromise((resolve,reject) => {
console.log('000')
resolve('ddd')
});
console.log('testP',testP); // 状态为fulfilled
const testP = new MPromise((resolve,reject) => {
console.log('000')
reject('错了')
});
console.log('testP',testP); // 状态为rejectd
总结:
-
new promise 如果不执行resolve, reject 状态始终为pending
-
执行 resolve ,状态为fulfilled
-
执行 reject, 状态为rejected
2.4 实现then
什么时候执行?(当状态变化成最终态的时候执行,也就是resolve,reject执行之后)
then(onFulfilled,onRejected) {
if(this.status === 'FULFILLED') {
onFulfilled(this.value);
}
if(this.status === 'REJECTED') {
onRejected(this.reason);
}
}
测试执行:
const testP = new MPromise((resolve,reject) => {
console.log('000')
resolve('dddd')
});
const testPthen= testP.then((a,b) => { // 出错了,onRejected不是一个函数
console.log('---',a);
});
优化修改then的实现: 规范中定义:如果传入的onFulfilledonRejected 不是函数的话,要给一个默认函数执行
isFun(fn) {
return typeof fn === 'function';
}
then(onFulfilled,onRejected) {
if(this.status === FULFILLED) {
const isOnFulfilled = this.isFun(onFulfilled)?onFulfilled:(value) => value;
isOnFulfilled(this.value);
}
if(this.status === REJECTED) {
const isOnRejected = this.isFun(onRejected)?onRejected:(reason) => reason;
isOnRejected(this.reason);
}
}
测试执行:
const testPthen= testP.then((ful,rej) => {
console.log('ful',ful);
console.log('rej',rej);
});
2.5 处理异步任务
当在promise中执行异步函数的时候,在异步中执行resolve,reject,因为promsie的返回值状态一直是pending,状态未到最终态,then也不会执行;
举例:
const testP = new MPromise((resolve,reject) => {
setTimeout(() => {
console.log('111')
resolve('这个值')
},1000)
});
console.log('testP',testP); // pending
testP.then((ful) => {
console.log('ful',ful) // undefined
})
如何解决?
- then 的时候,状态为pending, 把异步任务放到对应的队列中;
- resolve 或者reject执行的这个异步队列任务
const PENDING = 'PENDING';
const REJECTED = 'REJECTED';
const FULFILLED = 'FULFILLED';
class MPromise{
constructor(fn) {
this.value = undefined;
this.reason = undefined;
this.status = PENDING;
this.onFulfillListCallback = []; // 异步存储
this.onRejectedListCallback = []; // 异步存储
try { // 防止报错
fn(this.resolve.bind(this),this.reject.bind(this)); // 这里bind this,防止this丢失
} catch (error) {
this.reject(error);
}
}
resolve(newValue) {
if(this.status === PENDING) { // 状态只能从一种状态变成另外一种,不可逆
this.status = FULFILLED;
this.value = newValue;
this.onFulfillListCallback.forEach(fn => fn());
}
}
reject(newReason) {
if(this.status === 'PENDING') {
this.status = REJECTED;
this.reason = newReason;
this.onRejectedListCallback.forEach(fn => fn());
}
}
isFun(fn) {
return typeof fn === 'function';
}
then(onFulfilled,onRejected) {
const isOnFulfilled = this.isFun(onFulfilled)?onFulfilled:(value) => value;
const isOnRejected = this.isFun(onRejected)?onRejected:(reason) => reason;
if(this.status === FULFILLED) {
isOnFulfilled(this.value);
}
if(this.status === REJECTED) {
isOnRejected(this.reason);
}
if(this.status === PENDING) {
this.onFulfillListCallback.push(() => {
isOnFulfilled(this.value);
});
this.onRejectedListCallback.push(() => {
isOnRejected(this.reason);
});
}
}
}
测试代码:
const testP = new MPromise((resolve,reject) => {
setTimeout(() => {
console.log('111')
resolve('这个值')
},1000)
});
console.log('testP',testP); // fulfilled
testP.then((ful) => {
console.log('ful',ful) // 这个值
})
2.6 then返回是promise
暂未实现
3.Promise的各种方法的状态流转
测试代码1:
const PromiseA = new Promise((resolve,reject) => {
});
console.log('PromiseA',PromiseA); // pending
Promise.all: promise.all([PromiseA,PromiseB]);
- 全为fulfilled, all为 fulfilled
- 有一个rejected ,all 为 rejected
- 其他情况是 pending
Promise.race 最先返回的状态为准
- 都是pending race 为pending
- 最先返回fulfilled ,race 为fulfilled
- 最先返回的是rejected ,race 为rejected
Promise.allsettled 等所有的结果结束,才返回所有的值,状态为fulfilled,无rejected状态
-
有一个pending ,allsettled 为pending
-
等所有的状态都返回了(fulfilled 或者 rejected),allsettled 为fulfilled Promise.any
-
所有的pending , any 为pending
-
所有的为rejected ,any 为 rejected
-
有一个fulfilled ,any 为 fulfilled
finally 不以promsie的状态都要执行的方法,没有状态只说
const PromiseA = new Promise((resolve,reject) => {
reject('fff')
}).finally(() => {});
-
pending 为