导语:
你肯定使用过promise,但是你知道它是怎么实现的吗?它的原理是怎么样的?你能手写一个简单的promise吗?
在面试中你也可能会被问到手写一个promise,现在来直接手撕原理和代码吧!!
一,promise的状态
promise有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。
一开始的时候就是pending,随后经过操作就会产生出另外两种状态fulfilled和rejected,并且可以通过这两个状态去调用不同的处理函数。
二,仅仅考虑resolve和reject
首先我们先写一个class的构造函数,并且把默认state设置为pending,它的value和reason设置为null。
class Promise{
constructor(executor){
this.state = 'pending'; //默认的状态,进行中
this.value = null; //成功后携带的值
this.reason = null; //失败后携带的原因
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
function resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(item => item(this.value))
}
};
function reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(item => item(this.reason))
}
};
try{
executor(resolve, reject); //构造
} catch (err) {
reject(err);
}
}
//then函数根据state来进行后续的回调函数操作
then(onFulfilled,onRejected) {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
};
if (this.state === 'rejected') {
onRejected(this.reason);
};
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(onFulfilled)
this.onRejectedCallbacks.push(onRejected)
}
}
}
三,考虑能够链式then
如果要能够进行链式的then,那么肯定是要返回一个promise,才能够这样串联起来。所以我们要对刚刚的代码进行小小的修改,让then执行回调函数的时候,返回一个promise。
class Promise{
constructor(executor){
this.state = 'pending'; //默认的状态,进行中
this.value = null; //成功后携带的值
this.reason = null; //失败后携带的原因
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
function resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(item => item(this.value))
}
};
function reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(item => item(this.reason))
}
};
try{
executor(resolve, reject); //构造
} catch (err) {
reject(err);
}
}
//then函数根据state来进行后续的回调函数操作
then(onFulfilled,onRejected) {
if (this.state === 'fulfilled') {
return new Promise((resolve, reject) => {
onFulfilled(this.value)
})
};
if (this.state === 'rejected') {
return new Promise((resolve, reject) => {
onRejected(this.reason)
})
};
if (this.state === 'pending') {
return new Promise((resolve, reject) => {
this.onFulfilledCallbacks.push(onFulfilled)
this.onRejectedCallbacks.push(onRejected)
})
}
}
}
这样写后,我们就可以进行链式操作,比如promise.then().then()…,这样无限串联,解决了回调函数的回调地狱问题。
四,考虑链式,也考虑then也可能是返回一个值
class Promise{
constructor(executor){
this.state = 'pending'; //默认的状态,进行中
this.value = null; //成功后携带的值
this.reason = null; //失败后携带的原因
this.onFulfilledCallbacks = []
this.onRejectedCallbacks = []
function resolve(value) {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(item => item(this.value))
}
};
function reject(reason) {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(item => item(this.reason))
}
};
try{
executor(resolve, reject); //构造
} catch (err) {
reject(err);
}
}
//then函数根据state来进行后续的回调函数操作
then(onFulfilled,onRejected) {
if (this.state === 'fulfilled') {
return new Promise((resolve, reject) => {
try {
let f = onFulfilled(self.value)
if (f instanceof Promise) {
f.then(resolve, reject)
} else {
resolve(f)
}
} catch (err) {
reject(err)
}
})
};
if (this.state === 'rejected') {
return new Promise((resolve, reject) => {
try {
let j = onRejected(self.reason)
if (j instanceof Promise) {
j.then(resolve, reject)
} else {
resolve(j)
}
} catch (err) {
reject(err)
}
})
};
if (this.state === 'pending') {
return new Promise((resolve, reject) => {
self.onFulfilledCallbacks.push(() => {
let f = onFulfilled(self.value)
if (f instanceof Promise) {
f.then(resolve, reject)
} else {
resolve(f)
}
})
self.onRejectedCallbacks.push(() => {
let j = onRejected(self.reason)
if (j instanceof Promise) {
j.then(resolve, reject)
} else {
resolve(j)
}
})
})
}
}
}
这样的话promise也能返回一个值,并且被后续的then获取到。