最最最通俗易懂的promise手写系列(一)

先看一下这一次要讲的涉及到的promise的基础用法

let pms = new Promise((resolve, reject) => {
    setTimeout(() => {
        if (parseInt(Math.random()*10) > 5) {
             console.log('随机数大于5,算任务成功了')
             resolve('还可以传参哦')
        } else {
            console.log('随机数< 5,算任务失败了')
            reject('还可以传参哦< 5')
        }
    }, 1500)
  })

  pms.then((value) => {
    console.log('success', value)
  }, (reason) => {
    console.log('fail', reason)
  })
复制代码

1.5s后如果随机的数大于5走resolve()输出:
'随机数大于5,算任务成功了', 'success',
小于5走reject(),输出:
'随机数< 5,算任务失败了', 'fail'.

我们先写promise的这两个功能:

  1. 构造函数的参数接受一个函数。
  2. 函数在被调用的时候,会被promise传入两个参数resolve跟reject。
  function Promise(executor){
    executor(resolve, reject)
    function resolve(){}
    function reject(){}
  }
复制代码

可以看到一new Promise就会执行传入的函数,也就是我们起名为executor的函数.

  1. 大家肯定纳闷儿为啥要在executor里调用resolve或者reject,我们里先上代码:
  function Promise(executor) {
    let self = this;
    self.value = undefined;
    self.reason = undefined;
    self.status = 'pending';

    self.onFulFilledCallbacks = [];
    self.onRejectedCallbacks = [];

    function resolve(value) {
        if (self.status === 'pending') {
            self.value = value;
            self.status = 'resolved'

            self.onFulFilledCallbacks.forEach(onFulFilled => {
                onFulFilled(self.value)
            });
        }
    }
    function reject(reason) {
        if (self.status === 'pending') {
            self.reason = reason;
            self.status = 'rejected';
            self.onRejectedCallbacks.forEach(onRejected => {
                onRejected(self.reason)
            });
        }
    }

    try {
        executor(resolve, reject);
    } catch (error) {
        reject(error)
    }
}

Promise.prototype.then = function (onFulFilled, onRejected) {
    if (this.status === 'pending') {
        this.onFulFilledCallbacks.push(() => {
            onFulFilled(this.value)
        }); 
        this.onRejectedCallbacks.push(() => {
            onRejected(this.reason)
        })
    } else if (this.status === 'resolved') {
        onFulFilled(this.value);
    } else if (this.status === 'rejected') {
        onRejected(this.reason);
    }
}
复制代码
  • promise的三种状:等待pending,成功resolve,失败rejected.(说直接一点就是用来记录resolve或者reject是否已经调用,也就是常说的那个executor任务执行成功了还是失败了)

  • 这一次我们新增了两个数组onFulFilledCallbacks、onRejectedCallbacks用来保存调用then的时候传的两个回调函数(当然如果在调用then的时候已经resolve或reject,那就直接执行传入的函数,不用保存了),所以executor里一定会调用resolve或者reject中的一个,因为一个函数的执行不是(逻辑上成功)就是(逻辑上失败).对应我们写的例子就是随机数不是大于5就是小于5.

  • executor任务成功了肯定有成功后的结果,失败了我们肯定也拿到失败的原因。所以value与reason一个是用来保存成功的结果,一个是用来保存失败的原因。

  • ps:onFulFilledCallbacks、onRejectedCallbacks定为数组的原因是为了这个功能:

pms.then((value) => {
    console.log('success1', value)
  }, (reason) => {
    console.log('fail1', reason)
  })
pms.then((value) => {
    console.log('success2', value)
  }, (reason) => {
    console.log('fail2', reason)
  })
//then多次得把这些函数给存起来,到时候成功或者失败的时候,遍历依次执行~
复制代码

下一张我们进入Promise最迷人的链式调用.

猜你喜欢

转载自juejin.im/post/5b55c28ee51d45195a7139d6