这是我们上一章产出的代码,不了解的童鞋先简单看一看,了解了解
class MyPromise {
constructor(handle){
this.status = 'pending';
this.value = undefined ;
// this.resolveFn = null;
// this.rejectFn = null;
this.resolveFnQueue = [];
this.rejectFnQueue = [];
// 只能通过bind 绑定this 不能用 call apply
// 原因:这个函数的执行位置不在这,在自己的js逻辑执行
// 使用call apply会将函数执行
handle(this._resolve.bind(this),this._reject.bind(this))
}
_resolve(val){
this.status = "fulfilled";
this.value = val
const run = ( ) => {
// this.resolveFn(val)
let cb;
while(cb = this.resolveFnQueue.shift()){
cb && cb(val)
}
}
setTimeout(run)
}
_reject(val){
this.status = "rejected";
this.value = val
this.rejectFn(val)
const run = ( ) => {
// this.rejectFn(val)
let cb;
while(cb = this.resolveFnQueue.shift()){
cb && cb(val)
}
}
setTimeout(run)
}
then(onResolved,onRejected){
// 保存回调函数,不执行
// 执行 then 的地方为 _resolve _reject
// this.resolveFn = onResolved;
// this.rejectFn = onRejected;
this.resolveFnQueue.push(onResolved)
this.rejectFnQueue.push(onRejected)
}
}
上一章说到setTimeout是个宏任务,而promise是个微任务,那么我们来利用其中的一个微任务
MutationObserver来改进setTimeout
先说一下MutationObserver是怎么使用的
<script>
let ob = new MutationObserver(function(){
console.log('微任务')
})
ob.observe(document.body,{
attributes:true
})
document.querySelector('body').setAttribute('MutationObserver',true)
</script>
ob.observe的第二个属性
childList:子元素的变动
attributes:属性的变动
characterData:节点内容或节点文本的变动
subtree:所有下属节点(包括子节点和子节点的子节点)的变动
想要观察哪一种变动类型,就在option对象中指定它的值为true。需要注意的是,不能单独观察subtree变动,必须同时指定childList、attributes和characterData中的一种或多种。
所以修改后的代码为
class MyPromise {
constructor(handle){
this.status = 'pending';
this.value = undefined ;
// this.resolveFn = null;
// this.rejectFn = null;
this.resolveFnQueue = [];
this.rejectFnQueue = [