实现思路
- 1.属性做区分 :[[PromiseState]] [[PromiseResult]]
- 2.成功/失败:改变Promise 设置PromiseState属性的值 PromiseResult = value
- 3.this._resolve.bind(this) 外部调用this变化 type="module" 严格模式 this默认undefined
- 4.调用多个then的问题(不是链式操作) -- 队列保存回调
- 5.执行顺序问题(微任务(颗粒度小,精度高。当前宏任务之后,下一个宏任务之前) 宏任务(颗粒度比较大))—— 可能会先执行的resolve/reject 再注册的then回调
- 6.new mutationObserver 监听dom变化
- 7.链式操作
- 8.then的不同返回值构造promise
- 9.周边静态方法 resolve reject all allsettled finally
代码实现
export default class myPromise {
constructor(handle) {
this['[[PromiseState]]'] = 'pending'
this['[[PromiseResult]]'] = undefined
this.resolveList = []
this.rejectList = []
handle(this._resolve.bind(this), this._reject.bind(this))
}
then(onResolve, onReject) {
return new myPromise((resolve, reject) => {
this.resolveFn = function(val) {
let resolveResult = onResolve(val)
console.log('resolveResult:', resolveResult)
if(resolveResult instanceof myPromise) {
resolveResult.then(res=>{
resolve(res);
})
} else {
resolve(resolveResult);
}
}
this.resolveList.push(this.resolveFn)
this.rejectFn = function(err) {
let rejectResult = onReject(err)
if(rejectResult instanceof myPromise) {
rejectResult.then(res=>{
reject(res);
})
} else {
reject(rejectResult);
}
}
this.rejectList.push(this.rejectFn)
})
}
_resolve(val) {
this['[[PromiseState]]'] = 'fulfilled'
this['[[PromiseResult]]'] = val
const run = () => {
let cb;
console.log(this)
while(cb = this.resolveList.shift()) {
cb && cb(val)
}
}
let ob = new MutationObserver(run)
ob.observe(document.body, {attributes: true})
document.body.setAttribute('test', 123)
}
_reject(err) {
this['[[PromiseState]]'] = 'rejected'
this['[[PromiseResult]]'] = err
const run = () => {
let cb;
while(cb = this.rejectList.shift()) {
cb && cb(err)
}
}
let ob = new MutationObserver(run)
ob.observe(document.body, {attributes: true})
document.body.setAttribute('test', 123)
}
static resolve(val) {
return new myPromise((resolve, reject) => {
resolve(val)
})
}
static reject(err) {
return new myPromise((resolve, reject) => {
reject(err)
})
}
static race(list) {
return new myPromise((resolve, reject) => {
list.forEach(p => {
p.then(res => {
resolve(res)
}, err => {
reject(err)
})
});
})
}
static all(list) {
return new myPromise((resolve, reject) => {
let arr = []
let num = 0
list.forEach(p => {
p.then(res => {
arr.push(res)
num += 1
if(num == list.length) {
resolve(arr)
}
}, err => {
reject(err)
})
})
})
}
static allSettled(list) {
return new myPromise((resolve, reject) => {
let arr = []
let num = 0
list.forEach((p, key) => {
p.then(res => {
let obj = {}
obj['status'] = 'fulfilled'
obj['value'] = res
arr.push(obj)
num+=1
if(num == list.length) {
resolve(arr)
}
}, err => {
let obj = {}
obj.status = 'rejected'
obj.value = err
arr.push(obj)
num+=1
if(num == list.length) {
resolve(arr)
}
})
})
})
}
}