碎碎念,一直没手写过promise,看笔记注释少总理解不上去,看了后盾人的视频终于敲下来一遍,但也不完整,
原生promise
new Promise((resolve,reject) => {
...一些同步执行的代码...
resolve(value)或 reject(reason);
}).then(
value => {},
reason => {}
)
手写思路
promise对象,有三种状态,内部通过resolve,reject改变状态,可以调用then方法处理返回值
简易版
class Prms{
// promise对象的三个状态
static PENDING = 'pending';
static FULFILLED = 'fulfilled';
static REJECTED = 'rejected';
constructor(executor){
this.status = Prms.PENDING; //初始状态为pending
this.value = null; // promise的返回值,即resolve(value), 会传给then方法
this.callbacks = []; //以后要执行的函数 问题四
// 对应的是传给new Promise的函数,即(resolve,reject)=>{...;resolve()/reject()}
executor(this.resolve, this.reject) //下面问题一
}
resolve(value){
this.status = Prms.FULFILLED; //改变promise的状态为成功
this.value = value; //获取返回值,resolve(value)
}
reject(reason){
this.status = Prms.REJECTED;
this.value = reason;
}
then(onFulfilled, onRejected){ // then方法中接受2个函数,分别对成功/失败情况做处理
if(this.status === Prms.FULFILLED){ //状态改变后才会执行then方法
onFulfilled(this.value)
}
if(this.status === Prms.REJECTED){
onRejected(this.value)
}
}
}
问题一:executor内部同步的代码可能有报错,需要捕获,并且this需绑定
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (error) {
this.reject(error)
}
问题二:promise对象只可修改一次,之后访问也不会再改变
resolve(value){
if(this.status == Prms.PENDING){ //即只能从pending=>fulfilled / pending=>rejected
this.status = HD.FULFILLED;
this.value = value;
}
}
reject(reason)同理
问题三:.then是微任务,需要在同步代码后面执行
例如
let p = new Promise((resolve,reject)=>{
resolve(promise成功);
}).then(value=>{console.log(value)});
console.log('aaaa');
应该是先打印aaaa, 然后再打印promise成功;
then(onFulfilled, onRejected){
if(this.status === Prms.FULFILLED){
setTimeOut(()=>{
onFulfilled(this.value)
})
}
if(this.status === Prms.REJECTED){ //同上
onRejected(this.value)
}
}
问题四:new promise后会直接调用then方法,但这时状态可能还没改变
new Promise(()=>{
setTimeout(()=>{
resolve('aaa');
})
}).then(), 这时promise状态还是pending,
-
.then方法需增加pendging状态的处理
if (this.status === HD.PENDING) { // 把状态改变后要执行的函数放进callbacks里 this.callbacks.push({ onFulfilled, onRejected }) }2.resolve,reject方法也需执行相应函数
resolve(value){ this.status = Prms.FULFILLED; this.value = value; this.callbacks.map(callback => { callback.onFulfilled(value) }) } reject相同
问题五: aaa要先打印,然后才是解决。then是异步任务
new Promise(()=>{
setTimeOut(()=>{
resolve('解决');
console.log('aaaaa')
})
}).then(value => console.log(value ))
resolve/reject方法需要处理,回调函数放入settimeOut里,
resolve(value){
this.status = Prms.FULFILLED;
this.value = value;
setTimeOut(()=>{
this.callbacks.map(callback => {
callback.onFulfilled(value)
})
})
}
问题六:.then可以链式操作,因为.then返回的也是一个promise
new Promise((resolve,reject)=>{ resolve(成功)})
.then(value=>{ then1 }, reason=>{})
.then(value=>{ then2 },reason=>{})
promise状态改变,then1获取成功/失败,then2都是成功
修改then方法
if(this.status == Prms.FULFILLED){
setTimeout(()=>{
try {
let result = onFulFilled(this.value);
resolve(result);
} catch (error){
reject(error)
}
})
}
pending,rejected状态同样
问题七:then方法可能返回一个promise对象
new Promise((resolve,reject)=>{})
.then(value=>{
return new Promise((resolve, reject)=>{ resolve('then返回promise对象')})
}).then(......)
then方法需要对返回值进行判断
if(this.status == Prms.FULFILLED){
setTimeout(()=>{
try {
let result = onFulFilled(this.value);
if(result instanceof Prms){
result.then(
value => resolve(value);
reason => reject(reason)
) //返回的promise对象状态改变也要先调then方法
}else{
resolve(result);
}
} catch (error){
reject(error)
}
})
}
pending,rejected状态同样