美文网首页
用JavaScript自己手写一个promise

用JavaScript自己手写一个promise

作者: 阿昕_ | 来源:发表于2019-01-20 02:29 被阅读19次

    调用then的时候,如果异步任务已完成则执行成功或失败的回调,否则挂起队列。当promise状态改变的时候,调用挂起的队列,执行传入的then的回调函数。

    
        // promise本质:状态机
        // 1.当状态改变的时候,调用之前挂起的then队列
        // 2.then的时候执行对应的函数 并传参
        class MyPromise {
          constructor(fn) {
            this.res = null
            this.err = null
            this._status = 'pending' // 当前异步任务的执行状态
            this._queue = [] // 等待队列
    
            fn((res) => { // 异步任务成功时用户自主调用
              // console.log('成功');
              this.res = res
              this.status = 'resolved'
    
              this._queue.length && this._queue.forEach(item => { // 如果等待队列不为空 则调用传入的成功回调
                item.fn1(res)
              })
            }, (err) => { // 异步任务失败时用户自主调用
              // console.log('失败');
              this.err = err
              this.status = 'rejected'
    
              this._queue.length && this._queue.forEach(item => { // 如果等待队列不为空 则调用传入的失败回调
                item.fn2(res)
              })
            })
          }
    
          static all(arr) {
            let results = []
            return new MyPromise((resolve, reject) => {
              let i = 0
              next()
    
              function next() {
                arr[i].then((res) => {
                  results.push(res)
                  i++
                  if (i === arr.length) {
                    resolve(results)
                  } else {
                    next()
                  }
                }, (err) => {
                  reject(err)
                })
              }
            })
          }
    
          then(fn1, fn2) {
            // console.log('then');
            if (this.status === 'resolved') { // 执行then的时候异步任务已完成--状态为成功
              fn1(this.res)
            } else if (this.status === 'rejected') { // 执行then的时候异步任务已完成--状态为失败
              fn2(this.err)
            } else { // 执行then的时候异步任务未完成
              this._queue.push({fn1, fn2})
            }
            // console.log('等待队列', this._queue);
          }
        }
    
    
    
    
        // test
        let p1 = new MyPromise((resolve, reject) => {
          setTimeout(() => {
            resolve(1)
          }, 1000);
        })
        let p2 = new MyPromise((resolve, reject) => {
          setTimeout(() => {
            resolve(2)
          }, 1000);
        })
        p1.then((res) => {
          console.log('成功回调==>', res);
        }, (err) => {
          console.log('失败回调==>', err);
        })
    
        MyPromise.all([p1, p2]).then((res) => {
          console.log('all', res);
        }, (err) => {
          console.log('all', err);
        })
    

    相关文章

      网友评论

          本文标题:用JavaScript自己手写一个promise

          本文链接:https://www.haomeiwen.com/subject/yymtjqtx.html