Appearance
cx
Appearance
promise构造函数立即执行
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
reject('error')
})
promise
.then(() => {
console.log(3)
})
.catch(e => console.log(e))
console.log(4)
// 最终结果 1,2,4,3构造函数中定时任务辅助理解只执行一次
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('once')
resolve('success')
}, 1000)
})
promise.then(res => {
console.log(res)
})
promise.then(res => {
console.log(res)
})
// 最终结果 once,success,success事件循环Event Loot下的Promise如何执行
const p1 = () =>
new Promise((resolve, reject) => {
console.log(1);
let p2 = new Promise((resolve, reject) => {
console.log(2);
const timeOut1 = setTimeout(() => {
console.log(3);
resolve(4);
}, 0);
resolve(5);
});
resolve(6);
p2.then((arg) => {
console.log(arg);
});
});
const timeOut2 = setTimeout(() => {
console.log(8);
const p3 = new Promise((reject) => {
reject(9);
}).then((res) => {
console.log(res);
});
}, 0);
p1().then((arg) => {
console.log(arg);
});
console.log(10);
// 最终结果 1,2,10,5,6,8,9,3
/**
* 第一步提出宏任务,排出队列中有的异步任务
* --异步任务
* Promise构造函数创建p1 打印1
* Promise构造函数创建p2 打印2
* console.log(10) 打印10
* --异步任务
* timeOut2,timeOut1, p2.then, p1.then
* 第二步,宏任务执行完成执行异步任务,微任务优先执行
* 则 p2.then, p1.then 打印5,6
* 第三步,微任务执行完毕,返回宏任务下。从队列中去,timeOut2先被取出来执行 打印8,9
* 9是在微任务中所以优先与timeOut1执行
* timeOut1执行 打印3
* /
// 因为在p2当中已经resolve(5)了所以resolve(4)不打印,但是如果把resolve(5)注释则打印的顺序应该是1,2,10,6,8,9,3,4const PENDING = 'pending'
const FULFILL = 'fulfill'
const REJECTED = 'rejected'
// 模拟添加微任务队列
function runMicroTask(callback) {
if (process && process.nextTick) {
process.nextTick(callback)
} else if (MutationObserver) {
const p = document.createElement('p')
const ob = new MutationObserver(callback)
ob.observe(p, { childList: true })
p.innerHTML = '1'
} else {
setTimeout(callback, 0)
}
}
function isPromise(obj) {
return !!(obj && typeof obj === 'object' && typeof obj.then === 'function')
}
class MyPromise {
constructor(executor) {
this.state = PENDING
this.value = undefined
this.handlers = []
try {
executor(this.resolve.bind(this), this.reject.bind(this))
} catch (err) {
this.reject(err)
}
}
changeState(newState, value) {
if (this.state !== PENDING) {
return
}
this.state = newState
this.value = value
this.runHandler()
}
resolve(data) {
this.changeState(FULFILL, data)
}
reject(reason) {
this.changeState(REJECTED, reason)
}
pushHandler(executor, state, resolve, reject) {
this.handlers.push({
executor,
state,
resolve,
reject,
})
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.pushHandler(onFulfilled, FULFILL, resolve, reject)
this.pushHandler(onRejected, REJECTED, resolve, reject)
this.runHandler()
})
}
runHandler() {
if (this.state === PENDING) {
return
}
while (this.handlers[0]) {
const handler = this.handlers[0]
this.runOneHandler(handler)
this.handlers.shift()
}
}
runOneHandler({ executor, state, resolve, reject }) {
runMicroTask(() => {
if (this.state !== state) {
return
}
if (typeof executor !== 'function') {
this.state === FULFILL ? resolve(this.value) : reject(this.value)
}
try {
const result = executor(this.value)
if (isPromise(result)) {
result.then(resolve, reject)
}
resolve(result)
} catch (e) {
reject(e)
}
})
}
}Promise.myAll = proms => {
let res, rej
const p = new Promise((reslove, reject) => {
res = reslove
rej = reject
})
let i = 0
let result = []
let fulfiled = 0
for (const prom of proms) {
const index = i
i++
Promise.resolve(prom).then(data => {
// 完成的数据汇总到结果中
result[index] = data
// 判断是否全部完成
fulfiled++
if (fulfiled === i) {
res(result)
}
}, rej)
}
if (i === 0) {
res([])
}
return p
}
Promise.myAll([1, 2, 3, Promise.resolve(123)]).then(
res => {
console.log(res)
},
err => {
console.log(err, 'err')
}
)