1.首先来看一下promise常用场景
function chenPromise (arg) {
return new Promise (resolve, reject) {
if () {
doSomeThing(arg)
resolve(val)
} else {
reject(val)
}
}
}
chenPromise(arg).then(((val) => {}, (err) =>{})
知识兔2.了解promise状态
1.常规分三种:PENDING, RESOLVED, REJECTED
2.一开始promise状态是PENDING,当调用了resolve()之后promise的状态就被固定了即成功时的状态RESOLVED,当调用了reject()之后promise状态就被成了REJECTED了
3.上面说了一旦调用了reject()或者resolve()状态就不能被改变了,这一点也可以算是promise的缺陷吧
4.代码是怎么做到状态从pending到resolove就不会被改变了呢可通过代码如下
_resolve(){
window.addEventListener('message', (val)=>{
if (this.status !== KPromise.PENDING) return // 当状态已经被固定了就不会往下执行了
this.status = KPromise.RESOLVED // 当执行这个函数的时候状态就已经被固定了
this.value = val
let handler;
while(handler = this.resolveQueues.shift()){
handler(this.value)
}
})
}
知识兔3.控制.then()在resolve()后面执行
实现思路:当调用.then(resolvehandle,rejecthandle)方法时将resolvehandle和rejecthandle分别push到一个数组中,当resolve()执行时,遍历两个数组unshift()一次一队列先进先出方式依次执行
then(resolveHandler, rejectHandler) {
this.resolveQueues.push(resolveHandler)
this.rejectQueues.push(rejectHandler)
}
reject(){
知识兔 let handler;
while(handler = this.rejectQueues.shift()){ // 执行以队列方式(先进先出方式)执行被注册函数
handler(this.value)
}
}
resolve () {
知识兔let handler;
while(handler = this.resolveQueues.shift()){ // 执行以队列方式(先进先出方式)执行被注册函数
handler(this.value)
}
}
知识兔3.实现promise先于setTimeout执行
setTimeout(() => {console.log(123)}, 100)
promise().resolve().then(() => {console.log(456)})
结果是先输出456 在输出123
知识兔这里实现涉及事件循环以及异步任务的宏认为和微任务执行顺序,通过微任务先于宏认为先执行机制来实现,具体可以通过h5新增的messge方法来达到如下
resolve(val) {
window.addEventListener('message', (val)=>{ // 这里涉及到宏任务和微任务的区别,实现让promises里面的方法是先于setTimeout执行的
if (this.status !== KPromise.PENDING) return // 当状态已经被固定了就不会往下执行了
this.status = KPromise.RESOLVED // 当执行这个函数的时候状态就已经被固定了
this.value = val
let handler;
while(handler = this.resolveQueues.shift()){ // 执行以队列方式(先进先出方式)执行被注册函数
handler(this.value)
}
})
window.postMessage('') // h5新增
this._finally(this.value)
}
_rejected(val) {
window.addEventListener('message',()=>{ // 这里涉及到宏任务和微任务的区别,实现让promises里面的方法是先于setTimeout执行的
this.status = KPromise.REJECTED
let handler;
while(handler = this.rejectQueues.shift()){ // 执行以队列方式(先进先出方式)执行被注册函数
handler()
}
})
window.postMessage('') // node 中有prosee.nexTick()
this._finally(this.value)
}