• 自己的Promise


    废话不多说,直接上代码:

    class myPromise {
      constructor(fn) {
        this.status = 'pending';
        this.resolveCbs = [];
        this.rejectCbs = [];
        this.value = null;
        fn(this._resolve.bind(this), this._reject.bind(this));
        return this;
      }
      _resolve(val) {
        if (this.status === 'pending') {
          this.value = val;
          this.status = 'fulfilled';
          this.resolveCbs.forEach(cb => {
            cb(this.value);
          })
        }
      }
      _reject(err) {
        if (this.status === 'pending') {
          this.value = err;
          this.status = 'rejected';
          this.rejectCbs.forEach(cb => {
            cb(this.value);
          })
          // 如果没有处理函数,则直接抛错
          if (this.rejectCbs.length === 0) {
            throw err
          }
        }
      }
      then(resolveCb, rejectCb) {
        if (this.status !== 'pending') {
          const cb = this.status === 'fulfilled' ? resolveCb : rejectCb;
          const self = new myPromise((resolve, reject) => {
            this._handleCb(cb, this.value, resolve, reject, self);
          })
          return self;
        } else {
          const self = new myPromise((resolve, reject) => {
            if (typeof resolveCb === 'function') {
              this.resolveCbs.push(res => {
                this._handleCb(resolveCb, res, resolve, reject, self);
              })
            }
            if (typeof rejectCb === 'function') {
              this.rejectCbs.push(res => {
                this._handleCb(rejectCb, res, resolve, reject, self);
              })
            }
          })
          return self;
        }
      }
      catch(rejectCb) {
        return this.then(null, rejectCb)
      }
      _handleCb(cb, res, resolve, reject, self) {
        try {
          const ret = cb(res)
          if (ret instanceof Promise || ret instanceof myPromise) {
            if (ret === self) {
              throw new Error('检测到myPromise链式循环')
            }
            ret.then(res => resolve(res))
          } else {
            resolve(ret)
          }
        } catch (err) {
          reject(err)
        }
      }
    }
    new myPromise((resolve, reject) => {
      setTimeout(() => {
        resolve(456)
      }, 1000);
    }).then(res => {
      console.log(res)
      throw 'hualala'
    }).catch(err => {
      console.log('heng!!!')
      return new myPromise((resolve, reject) => {
        setTimeout(() => {
          reject(233)
        }, 1000);
      })
    }).then(res => {
      console.log(res)
    })

    这个简版的Promise已经可以实现到链式的地步了, 如果return是一个非Promise,则直接resolve,如果是Promise,则等then再resolve

     
  • 相关阅读:
    Java——方法的重载
    JS数据类型之String类型
    常用的正则表达式
    关于前端面试遇到的问题值类型和引用类型,1rem等于多少像素
    JS数据类型之Number类型
    常用前端面试题链接
    Wpf 父子容器的关系 ^
    心情 ^
    sharepoint_wf 启动窗口设计,支配给自由域用户 ^
    WPF 单个触发器、多个触发器、多条件触发器 ^
  • 原文地址:https://www.cnblogs.com/amiezhang/p/8006370.html
Copyright © 2020-2023  润新知