• 丁鹿学堂:从零开始手写promise(二)


    手写promise2

    前面打好了基础,现在就开始手写promise。我们定义一个Promise函数。
    定义一个二维数组,用于记录异步操作的信息。包括信息,状态等。
    定义返回的对象chain,定义全局的state状态
    protect 是绑定状态,成功和失败的回调才可以改变,所以不能直接绑定到返回的对象chain上。

      let tuples = [
        ["resolve",'done',container('once memory'),'resolved'],
        ["reject",'fail',container('once memory'),'rejected'],
      ]
      let state = 'pending'
      let chain = {} //promise返回的是一个对象
       let protect = {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我们遍历这个数组,去获取container这个函数容器,得到的是两个外形一样的对象,但是其实他们是完全不一样的两个功能,一个是处理成功的,一个是处理失败的。
    tuple【2】 其实就是这个容器。

      tuples.forEach((tuple,i)=>{
        let list = tuple[2]
        console.log(list)
      })
    
    • 1
    • 2
    • 3
    • 4

    我们通过tuple【3】 去获取回调执行的状态。这里下标写死是没问题的,因为这个二维数组是我们定义的。
    如果有状态,不管是成功还是失败,我们都往容器里去添加一个回调。在这个回调里我们可以进行状态的改变。
    同时给返回的chain对象上添加一些方法,比如then等。
    list.add 就是一个语法糖,我们通过done或者fail的调用,去向容器中添加成功或者失败的回调函数,

      tuples.forEach((tuple,i)=>{
        let list = tuple[2]
        let stateString = tuple[3]
        if(stateString){
          list.add(function(){
            state = stateString
          })
        }
        chain[tuple[1]] = list.add
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    我们还要给返回的对象上去绑定状态。因为我们知道promise的状态确定以后就无法改变。而且只有异步操作的结果可以改变这个状态。所以在函数内部定义一个对象去绑定状态(就是上面定义的protect)

      tuples.forEach((tuple,i)=>{
        let list = tuple[2]
        let stateString = tuple[3]
        if(stateString){
          list.add(function(){
            state = stateString
          })
        }
        chain[tuple[1]] = list.add
        protect[tuple[0]] = function(){
          protect[tuple[0]+'Bind'](this,arguments)
        }
        protect[tuple[0]+'Bind'] = list.startBind
      })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    整体的一个雏形就出来了:

    function Promise(func){
      let tuples = [
        ["resolve",'done',container('once memory'),'resolved'],
        ["reject",'fail',container('once memory'),'rejected'],
      ]
      let state = 'pending'
      let protect = {}
      let chain = {} //promise返回的是一个对象
      tuples.forEach((tuple,i)=>{
        let list = tuple[2]
        let stateString = tuple[3]
        if(stateString){
          list.add(function(){
            state = stateString
          })
        }
        chain[tuple[1]] = list.add
        protect[tuple[0]] = function(){
          protect[tuple[0]+'Bind'](this,arguments)
        }
        protect[tuple[0]+'Bind'] = list.startBind
      })
      if(func){
        func.call(chain,protect['resolve'],protect['reject'])
      }
      return chain
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    JNI中javah命令的使用,生成.h的头文件
    OkHttp报unexcepted end of stream on...错误分析
    RabbitMQ简介
    计算机基础内容——网络基础
    教培机构如何抢占招生市场
    openglES多纹理
    hadoop-2.7.3安装
    【项目开发】成长与收获
    Linux网络基础
    jenkins使用docker安装保姆级教程(面向小白教程,最新最全,全图文)2022-8-1,不会docker也没关系
  • 原文地址:https://blog.csdn.net/qq_38525381/article/details/127656369