const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
const { instanceQueve, timerFunc } = (() => {
let instanceQueve = []
let counter = 1
const observer = new MutationObserver(() => {
const tempQueve = instanceQueve.slice().reverse()
let len = tempQueve.length
while(len--) {
const instance = tempQueve[len]
if(instance.status == FULFILLED) {
instance.onFulfilled.forEach(cb => cb())
} else {
instance.onRejected.forEach(cb => cb())
}
instanceQueve.shift()
}
})
const textNode = document.createTextNode(String(counter))
observer.observe(textNode, {
characterData: true
})
const timerFunc = () => {
counter = (counter + 1) % 2
textNode.data = String(counter)
}
return {
instanceQueve,
timerFunc
}
})()
function decisionTask() {
if (
MutationObserver !== 'undefined' || (
MutationObserver.toString() === '[object MutationObserverConstructor]')
) {
timerFunc()
instanceQueve.push(this)
return
}
setTimeout(() => {
if(this.status == FULFILLED) {
this.onFulfilled.forEach(cb => cb())
} else {
this.onRejected.forEach(cb => cb())
}
}, 0)
}
function LPromise(executor) {
this.status = PENDING
this.value = undefined
this.onFulfilled = []
this.onRejected = []
this.resolveFn = body => {
if (this.status !== PENDING) return
this.status = FULFILLED
this.value = body
decisionTask.call(this)
}
this.rejectFn = error => {
if (this.status !== PENDING) return
this.status = REJECTED
this.value = error
decisionTask.call(this)
}
try {
executor(this.resolveFn, this.rejectFn)
} catch (e) {
this.rejectFn(e)
}
}
LPromise.prototype.then = function (onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : () => { }
onRejected = typeof onRejected === 'function' ? onRejected : () => { }
const _promise = new LPromise((resolve, reject) => {
this.onFulfilled.push(() => {
try {
const result = onFulfilled(this.value)
resolve(result)
} catch (e) {
reject(e)
}
})
this.onRejected.push(() => {
try {
const result = onRejected(this.value)
resolve(this.value)
} catch (e) {
reject(e)
}
})
})
return _promise
}
LPromise.prototype.catch = function (onRejected) {
this.then(null, onRejected)
}
LPromise.resolve = function (value) {
return new LPromise((resolve, reject) => {
resolve(value)
})
}
LPromise.reject = function (value) {
return new LPromise((resolve, reject) => {
reject(value)
})
}
console.log('script start')
LPromise.resolve(1).then(res => console.log(res)).then(res => console.log(res))
p = LPromise.resolve(2)
p.then(res => console.log(res))
p.then(res => console.log(res))
const lp1 = new LPromise((resolve, reject) => {
a
})
lp1.then(body => { }, error => {
console.log(error, 'err')
})
const lp2 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve('sleep 1000ms')
}, 1000)
})
lp2.then(body => {
console.log(body)
return 1
}, null)
const lp3 = new LPromise((resolve, reject) => {
setTimeout(() => {
reject('失败了')
}, 1000)
})
lp3.then()
lp3.catch(fail => console.log(fail, ' lp3 err'))
const lp4 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1)
})
lp4
.then(body => {
console.log(body)
return '嘻哈'
}, null)
.then(body => {
console.log(body)
return 1
}, null)
const lp5 = new LPromise((resolve, reject) => {
setTimeout(() => {
resolve('测试 then 里面抛出异常')
}, 10)
})
lp5
.then(body => {
console.log(body)
console.log(b)
return '嘻哈'
}, null)
.then(null, error => {
console.log('上一个 then 里面抛出了异常,被我接收到了哦!!')
console.log(error)
})
LPromise.resolve(setTimeout(() => console.log('setTimeout'), 1000))
.then(body => console.log(body, 'Promise.resolve'))
LPromise.reject(setTimeout(() => console.log('setTimeout'), 1000))
.then(null, body => console.log(body, 'Promise.reject'))
console.log('script end')
console