function MyPromise(func) {
this.status = 'pending' // resolve, reject
this.thenFuncs = []
this.catchFuncs = []
this.value = undefined
func(MyPromise.resolve.bind(this), MyPromise.reject.bind(this))
}
MyPromise.resolve = function(result) {
this.value = result
this.status = 'resolve'
this.thenFuncs.forEach(func => func(result))
}
MyPromise.reject = function(error) {
this.value = error
this.status = 'reject'
this.catchFuncs.forEach(func => func(error))
}
MyPromise.prototype.then = function(thenFunc) {
if (this.status === 'resolve') {
thenFunc(this.value)
} else {
this.thenFuncs.push(thenFunc)
}
return this
}
MyPromise.prototype.catch = function(catchFunc) {
if (this.status === 'reject') {
catchFunc(this.value)
} else {
this.catchFuncs.push(catchFunc)
}
return this
}
// ----- start ----------
new MyPromise((resolve, reject) => {
if (false) {
setTimeout(() => {
resolve(123)
}, 3000)
} else {
reject('error')
}
}).then(result => {
console.log(result)
}).then(result => {
console.log(result)
}).then(result => {
console.log(result)
}).catch(error => {
console.log(error)
}).catch(error => {
console.log(error)
}).catch(error => {
console.log(error)
})
We will find that when we use our own encapsulated Promise, when the method passed in our new Promise is not an asynchronous method, then its .then will be executed first, which is somewhat inconsistent with the original Promise
In fact, it is because the original Promise adds tasks to microtasks
The queueMicrotask API of window is used
queueMicrotask(() => {
/* 微任务中将运行的代码 */
});