手写promise

手写promise的过程是按照promise A+标准,先写测试用例,然后测试驱动开发,开发一个满足测试用例的promise。

class Promise2 {
  state = "pending";
  callbacks = [];
  resolve(result) {
    if (this.state !== 'pending') return
    this.state = 'fulfilled'
    nextTick(() => {
      this.callbacks.forEach((handle) => {
        if (typeof handle[0] === 'function') {
          handle[0].call(undefined,result)
        } 
      })
    })
  }
  reject(reason) {
    if (this.state !== 'pending') return
    this.state = 'rejected'
    nextTick(() => {
      this.callbacks.forEach((handle) => {
        if (typeof handle[1] === 'function') {
          handle[1].call(undefined,reason)
        } 
      })
    })
  }
  constructor(fn) {
    if(typeof fn != 'function'){
      throw new Error('Promise必须传入一个函数类型的参数')
    }
    fn(this.resolve.bind(this),this.reject.bind(this))
  }
  then(succeed?, fail?) {
    const handle = []
    if (typeof succeed === 'function') {
      handle[0] = succeed
    }
    if (typeof fail === 'function') {
      handle[1] = fail
    }
    this.callbacks.push(handle)
 
  }
}

export default Promise2;

function nextTick(fn) {
  if (process !== undefined && typeof process.nextTick === "function") {
    return process.nextTick(fn);
  } else {
    var counter = 1;
    var observer = new MutationObserver(fn);
    var textNode = document.createTextNode(String(counter));

    observer.observe(textNode, {
      characterData: true
    });

    counter = counter + 1;
    textNode.data = String(counter);
  }
}

总结:

1.promise有且只有三个状态:pending、fulfilled、rejected,状态之间的转换是只允许pending转向fulfilled或rejected,其它任何状态都不能相互转换。

2.封装的nextTick函数是用来兼容node环境和浏览器环境的,如果是node环境会直接使用process.nextTick;如果是浏览器环境,使用MutationObserver API来实现。(MutationObserver 接口提供了监视对 DOM 树所做更改的能力)

3.注意在写调用函数时,多想想函数的this是什么,是否符合我们预期的this,如果不符合,就需要使用bind或call方法指定函数的this。

下面是一个MutationObserver例子

<html>
<p id="domp">111</p>
</html>

<script>

setTimeout(()=>{
  console.log('setTimeout')
})
nextTick(()=>{
  console.log('nextTick执行了')
})
domp.innerHTML = 'hello'


new Promise((resolve,reject)=>{
  console.log('new promise')
  resolve()
}).then(()=>{
  console.log('promise.then执行了')
})

/*
new promise
nextTick执行了
promise.then执行了
setTimeout
*/
function nextTick(fn) {
    var counter = 1;
    var observer = new MutationObserver(fn);
    var textNode = document.createTextNode(String(counter));

    observer.observe(textNode, {
      characterData: true
    });

    counter = counter + 1;
    textNode.data = String(counter);
}

</script>

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值