实现一个最简单的promise例子
- 从使用层面分析,使用promise时,需要实例化Promise构造函数
- Promise有三种状态,pendding,resolved,rejected
- 构造函数立即执行
通过此三条分析,可以写出一个最简单的例子
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
}
then(successCallback, failCallback) {
successCallback(this.value)
}
}
let p = new myPromise((resolve, reject) => {
resolve('成功')
})
p.then(res => {
console.log(res);
}, res => {
console.log(res);
});
- 通过结果可知,可以正常得到resolve中传入的值。
- 但是如果resolve异步执行,就拿不到值了,案例代码如下
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
}
then(successCallback, failCallback) {
successCallback(this.value)
}
}
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
})
})
p.then(res => {
console.log(res); // 成功
}, res => {
console.log(res);
});
- 针对异步情况的优化
- resolve异步执行,执行then函数时,status的状态为pendding,还没有执行resolve方法,所以需要一个数组来存储函数,当value没有值时,把函数存到栈中。
- 代码如下
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
successCallbackList = []
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
if (this.successCallbackList.length > 0) {
this.successCallbackList.shift()(value);
}
}
then(successCallback, failCallback) {
if(!this.value) {
this.successCallbackList.push(successCallback)
} else {
successCallback(this.value)
}
}
}
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
})
})
p.then(res => {
console.log(res); // 成功
}, res => {
console.log(res);
});
- 如果then执行多次就拿不到值了,代码如下
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
successCallbackList = []
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
if (this.successCallbackList.length > 0) {
this.successCallbackList.shift()(value);
}
}
then(successCallback, failCallback) {
if(!this.value) {
this.successCallbackList.push(successCallback)
} else {
successCallback(this.value)
}
}
}
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
})
})
p.then(res => {
console.log(res); // 成功
}, res => {
console.log(res);
});
p.then(res => {
console.log(res); // 不执行
}, res => {
console.log(res);
});
- 需要针对传入successCallbackList的函数依次出栈,代码如下
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
successCallbackList = []
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
while (this.successCallbackList.length) {
this.successCallbackList.shift()(value);
}
}
then(successCallback, failCallback) {
if(!this.value) {
this.successCallbackList.push(successCallback)
} else {
successCallback(this.value)
}
}
}
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
})
});
p.then(res => {
console.log(res); // 成功
}, res => {
console.log(res);
});
p.then(res => {
console.log(res); // 成功
}, res => {
console.log(res);
});
- 在使用promise时,then支持链式调用,所以在then函数中,要返回一个新的promise
- 还需要判断在then中返回的是常量还是一个promise
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
successCallbackList = []
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
while (this.successCallbackList.length) {
this.successCallbackList.shift()(value);
}
}
then(successCallback, failCallback) {
let promiseResolve = new myPromise((resolve, reject) => {
if (this.status === 'resolved') {
let result = successCallback(this.value);
this.resolvePromise(result, resolve, reject);
} else {
this.successCallbackList.push(successCallback)
}
});
return promiseResolve;
}
resolvePromise(result, resolve, reject) {
if (result instanceof myPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
}
}
let p = new myPromise((resolve, reject) => {
resolve('成功');
});
p.then(res => {
console.log(res); // 成功
return '链式调用';
}, res => {
console.log(res);
}).then(res=>{
console.log(res); // 链式调用
})
- 针对resolve异步时,还需要特殊处理
class myPromise {
constructor(exector) {
exector(this.resolve, this.reject);
}
value = undefined
status = 'pendding'
successCallbackList = []
resolve = (value) => {
if (this.status !== 'pendding') return
this.value = value;
this.status = 'resolved'
while (this.successCallbackList.length) {
this.successCallbackList.shift()(value);
}
}
then(successCallback, failCallback) {
let promiseResolve = new myPromise((resolve, reject) => {
if (this.status === 'resolved') {
let result = successCallback(this.value);
this.resolvePromise(result, resolve, reject);
} else {
this.successCallbackList.push(()=>{
let result = successCallback(this.value);
this.resolvePromise(result, resolve, reject);
})
}
});
return promiseResolve;
}
resolvePromise(result, resolve, reject) {
if (result instanceof myPromise) {
result.then(resolve, reject)
} else {
resolve(result)
}
}
}
let p = new myPromise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
})
});
p.then(res => {
console.log(res); // 成功
return '链式调用';
}, res => {
console.log(res);
}).then(res=>{
console.log(res); // 链式调用
})
- 除此之外,还需要补充异常时的调用以及兼容性处理
- then的