跟着大牛老师学的,手写一个promise,话不多说,直接放代码。
var MyPromise = (() => {
const PENDING = 'pending',
FULLFILLED = 'fullfilled',
REJECT = 'reject',
PromiseState = Symbol('PromiseState'),
PromiseResult = Symbol('PromiseResult'),
changeState = Symbol('changeState'),
thenableList = Symbol('thenableList'),
catchableList = Symbol('catchableList'),
addPromiseMethod = Symbol('addPromiseMethod'),
exePromiseMethod = Symbol('exePromiseMethod'),
linkPromise = Symbol('linkPromise'),
isFunction = (func) => {
return typeof func === 'function'
};
const MyPromise = class {
// 改变状态
[changeState](state, value) {
this[PromiseResult] = value;
// 改变promise状态
if (this[PromiseState] === PENDING) {
// 已经改变状态的就不能再改变了
this[PromiseState] = state
setTimeout(() => {
if (this[PromiseState] === FULLFILLED) {
this[exePromiseMethod](this[thenableList])
} else {
this[exePromiseMethod](this[catchableList])
}
}, 0)
}
}
// 添加执行函数
[addPromiseMethod](queue, method, state) {
if (isFunction(method)) {
queue.push(method);
// 如果该状态已经是fullfill则直接执行
if (this[PromiseState] === state) {
this[exePromiseMethod](queue)
}
}
}
// 执行
[exePromiseMethod](queue) {
queue.forEach(func => func(this[PromiseResult]))
}
// 返回的promise混入用户的执行方法
[linkPromise](queue, method, state) {
// 把用户的thenable函数和catchable函数混入promise,在then和catch方法返回新的MyPromise,用于链式调用
return new MyPromise((resolve, reject) => {
this[addPromiseMethod](queue, (param) => {
try {
// 获取thenable函数和catchable函数的执行结果
let result = method(param);
// 如果是MyPromise类型 则执行后改变新MyPromise
if (result instanceof MyPromise) {
// 新MyPromise的状态和用户返回的MyPromise状态保持一致
result.then(res => {
resolve(res)
}, err => {
reject(err)
})
} else {
resolve(result);
}
} catch (e) {
reject(e)
}
}, state)
})
}
// executor 生成promise实例时传递的unsettle状态的执行方法
constructor(executor) {
// 如果不是函数也不是MyPromise类型,抛出异常
if (!isFunction(executor)) {
throw new TypeError('Promise resolver undefined is not a function')
}
// 默认为pending状态
this[PromiseState] = PENDING;
// 默认为pending状态
this[PromiseResult] = undefined;
// 默认结果值未undefined
this[thenableList] = [];
this[catchableList] = [];
// 改变状态的入口方法
const changeStateEntry = (state,value)=>{
// 如果是MyPromise则执行后改变状态
if (value instanceof MyPromise) {
value.then(res => {
resolve(res)
}, err => {
reject(err)
})
} else {
// 如果不是则改变状态
setTimeout(() => {
this[changeState](state, value)
}, 0)
}
}
// 如果直接调用则在executor立马调用resolve 或reject时初始化的MyPomise状态不是pending
const resolve = (value) => {
changeStateEntry(FULLFILLED,value)
}
// 如果直接调用则在executor立马调用resolve 或reject时初始化的MyPomise状态不是pending
const reject = (value) => {
changeStateEntry(REJECT,value)
}
// 在最后执行,并两个形参,一个是resolve函数,一个是reject函数
// 如果executor执行失败则自动调用reject
try {
executor(resolve, reject)
} catch (e) {
// 执行异常时promise的状态立即为reject
this[changeState](REJECT, e)
setTimeout(() => {
throw e;
}, 0)
}
}
// then方法
// 有两个参数,一个是thenable方法,一个是catchable方法,
then(thenable, catchable) {
let pro = this[linkPromise](this[thenableList], thenable, FULLFILLED)
this.catch(catchable)
return pro
}
// catch方法
// 一个参数
catch (catchable) {
return this[linkPromise](this[catchableList], catchable, REJECT)
}
}
return MyPromise
})()
var pro = new MyPromise((resolve, reject) => {
resolve(new MyPromise((a, b) => {
setTimeout(() => {
console.log('执行了')
a(22)
}, 1000)
}))
}).then((res) => {
return new MyPromise((a, b) => {
setTimeout(() => {
a(24)
}, 1000)
})
}, (err) => {
console.log('err', err)
}).then((res) => {
console.log(res)
}, err => {
console.log('err', err)
})