zoukankan      html  css  js  c++  java
  • Promise内部实现原理

    promise内部实现原理:

    function $Promise(fn) {
      // Promise 的三种状态
      this.PENDING = 'pending'
      this.RESOLVED = 'resolved'
      this.REJECTED = 'rejected'
    
      this.onResolvedCallback = [] // 成功回调队列
      this.onRejectedCallback = [] // 失败回调队列
      this.status = this.PENDING // 初始状态
    
      // 成功函数处理
      const resove = (val) => {
        if (val instanceof $Promise) {
          return value.then(resolve, reject)
        }
        this.triggerResolve(val)
      }
      // 失败函数处理
      const reject = (val) => {
        this.triggerReject(val)
      }
    
      try {
        // 初始同步执行
        fn(resove, reject)
      } catch (err) {
        this.triggerReject(err)
      }
    }
    
    $Promise.prototype = {
      then(onResolved, onRejected) {
        // then参数不为函数则使用空函数,缺省函数返回当前值是为了 .then().then() 场景调用
        onResolved = typeof onResolved === 'function' ? onResolved : function (value) { return value }
        onRejected = typeof onRejected === 'function' ? onRejected : function (reason) { return reason }
    
        // Promise的then方法返回的是新的Promise对象,状态不会更改
        return new $Promise((resolve, reject) => {
          // 成功回调事件处理
          const resolveHandle = val => {
            let res = onResolved(val)
            if (res instanceof $Promise) {
              res.then(resolve, reject)
            } else {
              resolve(res)
            }
          }
          // 失败回调事件处理
          const rejectHandle = val => {
            const res = onRejected(val)
            if (res instanceof $Promise) {
              res.then(resolve, reject)
            } else {
              reject(res)
            }
          }
          // 当状态已经确认则立即执行
          if (this.status === this.RESOLVED) {
            return resolveHandle(this.value)
          }
          if (this.status === this.REJECTED) {
            return rejectHandle(this.value)
          }
          // 当当前状态没有确认,则将回调函数放入队列,等待确认后再一次执行
          this.onResolvedCallback.push(resolveHandle)
          this.onRejectedCallback.push(rejectHandle)
        })
      },
      // 状态确认后,成功回调队列的函数依次执行
      triggerResolve(val) {
        let _this = this
        setTimeout(() => {
          _this.value = val
          if (_this.status === _this.PENDING) {
            _this.status = _this.RESOLVED
            _this.onResolvedCallback.forEach(it => {
              it(val)
            })
          }
        })
      },
      // 状态确认后,失败回调队列的函数依次执行
      triggerReject(val) {
        let _this = this
        setTimeout(() => {
          _this.value = val
          if (_this.status === _this.PENDING) {
            _this.status = _this.REJECTED
            _this.onRejectedCallback.forEach(it => {
              it(val)
            })
          }
        })
      },
      // 最后捕捉调用链错误
      catch(onRejected) {
        return this.then(null, onRejected)
      },
      // finally实现,不管成功还是失败,都执行
      finally(callback) {
        return this.then((value) => {
          return $Promise.resolve(callback()).then(() => value);
        }, (err) => {
          return $Promise.resolve(callback()).then(() => err);
        });
      }
    }
    // 单独调用Promise.resolve方法实现
    $Promise.resolve = val => {
      return new $Promise((resolve) => {
        resolve(val)
      })
    }
    // 单独调用Promise.reject方法实现
    $Promise.reject = val => {
      return new $Promise((resolve, reject) => {
        reject(val)
      })
    }
    // race函数的实现,返回结果最先完成
    $Promise.race = values => {
      return new $Promise((resolve, reject) => {
        let len = values.length
        if (!len) return
        for (let i = 0; i < len; i++) {
          values[i].then(res => {
            resolve(res)
          }, error => {
            reject(error)
          })
        }
      })
    }
    // all函数实现,如有错误立即返回,没有错误,等待全部完成再返回
    $Promise.all = values => {
      return new $Promise((resolve, reject) => {
        let len = values.length
        if (!len) return
        let resolves = []
        let nums = 0
        function processValue(i, val) {
          resolves[i] = val
          if (++nums === len) {
            resolve(resolves)
          }
        }
        for (let i = 0; i < len; i++) {
          values[i].then(res => {
            processValue(i, res)
          }, error => {
            reject(error)
          })
        }
      })
    }
     
  • 相关阅读:
    C# get folder's Md5 generated by file's and filename's md5. get dictionary md5
    C# DataTable to List<T> based on reflection.
    C# MySql Transaction Async
    C# read file to bytes,File.ReadAllFiles,File.Open(),BinaryReader
    C# get md5,renamed file and can not change file's md5
    C# copy source directory files with original folder to the destination path
    C# transfer local file to remote server based on File.Copy
    C# copy folder and files from source path to target path
    vue slot
    vue 全局配置键盘事件
  • 原文地址:https://www.cnblogs.com/kdcg/p/13235871.html
Copyright © 2011-2022 走看看