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

    一 Promise 实现原理:https://www.jianshu.com/p/43de678e918a

      1   // 判断变量否为function
      2   const isFunction = variable => typeof variable === 'function'
      3   // 定义Promise的三种状态常量
      4   const PENDING = 'PENDING'
      5   const FULFILLED = 'FULFILLED'
      6   const REJECTED = 'REJECTED'
      7 
      8   class MyPromise {
      9     constructor (handle) {
     10       if (!isFunction(handle)) {
     11         throw new Error('MyPromise must accept a function as a parameter')
     12       }
     13       // 添加状态
     14       this._status = PENDING
     15       // 添加状态
     16       this._value = undefined
     17       // 添加成功回调函数队列
     18       this._fulfilledQueues = []
     19       // 添加失败回调函数队列
     20       this._rejectedQueues = []
     21       // 执行handle
     22       try {
     23         handle(this._resolve.bind(this), this._reject.bind(this)) 
     24       } catch (err) {
     25         this._reject(err)
     26       }
     27     }
     28     // 添加resovle时执行的函数
     29     _resolve (val) {
     30       const run = () => {
     31         if (this._status !== PENDING) return
     32         this._status = FULFILLED
     33         // 依次执行成功队列中的函数,并清空队列
     34         const runFulfilled = (value) => {
     35           let cb;
     36           while (cb = this._fulfilledQueues.shift()) {
     37             cb(value)
     38           }
     39         }
     40         // 依次执行失败队列中的函数,并清空队列
     41         const runRejected = (error) => {
     42           let cb;
     43           while (cb = this._rejectedQueues.shift()) {
     44             cb(error)
     45           }
     46         }
     47         /* 如果resolve的参数为Promise对象,则必须等待该Promise对象状态改变后,
     48           当前Promsie的状态才会改变,且状态取决于参数Promsie对象的状态
     49         */
     50         if (val instanceof MyPromise) {
     51           val.then(value => {
     52             this._value = value
     53             runFulfilled(value)
     54           }, err => {
     55             this._value = err
     56             runRejected(err)
     57           })
     58         } else {
     59           this._value = val
     60           runFulfilled(val)
     61         }
     62       }
     63       // 为了支持同步的Promise,这里采用异步调用
     64       setTimeout(run, 0)
     65     }
     66     // 添加reject时执行的函数
     67     _reject (err) { 
     68       if (this._status !== PENDING) return
     69       // 依次执行失败队列中的函数,并清空队列
     70       const run = () => {
     71         this._status = REJECTED
     72         this._value = err
     73         let cb;
     74         while (cb = this._rejectedQueues.shift()) {
     75           cb(err)
     76         }
     77       }
     78       // 为了支持同步的Promise,这里采用异步调用
     79       setTimeout(run, 0)
     80     }
     81     // 添加then方法
     82     then (onFulfilled, onRejected) {
     83       const { _value, _status } = this
     84       // 返回一个新的Promise对象
     85       return new MyPromise((onFulfilledNext, onRejectedNext) => {
     86         // 封装一个成功时执行的函数
     87         let fulfilled = value => {
     88           try {
     89             if (!isFunction(onFulfilled)) {
     90               onFulfilledNext(value)
     91             } else {
     92               let res =  onFulfilled(value);
     93               if (res instanceof MyPromise) {
     94                 // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
     95                 res.then(onFulfilledNext, onRejectedNext)
     96               } else {
     97                 //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
     98                 onFulfilledNext(res)
     99               }
    100             }
    101           } catch (err) {
    102             // 如果函数执行出错,新的Promise对象的状态为失败
    103             onRejectedNext(err)
    104           }
    105         }
    106         // 封装一个失败时执行的函数
    107         let rejected = error => {
    108           try {
    109             if (!isFunction(onRejected)) {
    110               onRejectedNext(error)
    111             } else {
    112                 let res = onRejected(error);
    113                 if (res instanceof MyPromise) {
    114                   // 如果当前回调函数返回MyPromise对象,必须等待其状态改变后在执行下一个回调
    115                   res.then(onFulfilledNext, onRejectedNext)
    116                 } else {
    117                   //否则会将返回结果直接作为参数,传入下一个then的回调函数,并立即执行下一个then的回调函数
    118                   onFulfilledNext(res)
    119                 }
    120             }
    121           } catch (err) {
    122             // 如果函数执行出错,新的Promise对象的状态为失败
    123             onRejectedNext(err)
    124           }
    125         }
    126         switch (_status) {
    127           // 当状态为pending时,将then方法回调函数加入执行队列等待执行
    128           case PENDING:
    129             this._fulfilledQueues.push(fulfilled)
    130             this._rejectedQueues.push(rejected)
    131             break
    132           // 当状态已经改变时,立即执行对应的回调函数
    133           case FULFILLED:
    134             fulfilled(_value)
    135             break
    136           case REJECTED:
    137             rejected(_value)
    138             break
    139         }
    140       })
    141     }
    142     // 添加catch方法
    143     catch (onRejected) {
    144       return this.then(undefined, onRejected)
    145     }
    146     // 添加静态resolve方法
    147     static resolve (value) {
    148       // 如果参数是MyPromise实例,直接返回这个实例
    149       if (value instanceof MyPromise) return value
    150       return new MyPromise(resolve => resolve(value))
    151     }
    152     // 添加静态reject方法
    153     static reject (value) {
    154       return new MyPromise((resolve ,reject) => reject(value))
    155     }
    156     // 添加静态all方法
    157     static all (list) {
    158       return new MyPromise((resolve, reject) => {
    159         /**
    160          * 返回值的集合
    161          */
    162         let values = []
    163         let count = 0
    164         for (let [i, p] of list.entries()) {
    165           // 数组参数如果不是MyPromise实例,先调用MyPromise.resolve
    166           this.resolve(p).then(res => {
    167             values[i] = res
    168             count++
    169             // 所有状态都变成fulfilled时返回的MyPromise状态就变成fulfilled
    170             if (count === list.length) resolve(values)
    171           }, err => {
    172             // 有一个被rejected时返回的MyPromise状态就变成rejected
    173             reject(err)
    174           })
    175         }
    176       })
    177     }
    178     // 添加静态race方法
    179     static race (list) {
    180       return new MyPromise((resolve, reject) => {
    181         for (let p of list) {
    182           // 只要有一个实例率先改变状态,新的MyPromise的状态就跟着改变
    183           this.resolve(p).then(res => {
    184             resolve(res)
    185           }, err => {
    186             reject(err)
    187           })
    188         }
    189       })
    190     }
    191     finally (cb) {
    192       return this.then(
    193         value  => MyPromise.resolve(cb()).then(() => value),
    194         reason => MyPromise.resolve(cb()).then(() => { throw reason })
    195       );
    196     }
    197   }
    View Code

  • 相关阅读:
    Python在程序中进行多任务操作-协程
    Python-异常处理
    Python多任务-协程
    【每日一具4】TikTok 抖音国际版(网站)使用起来非常简单,无需FQ随便看
    【每日一具3】优美APP一款好用的短视频软件,优美APP专注于各种小姐姐短视频
    Python在程序中进行多任务操作-线程
    Python在程序中进行多任务操作-进程
    Python多任务-线程
    Python多任务-进程
    【每日一具3】优美APP一款好用的短视频软件,优美APP专注于各种小姐姐短视频
  • 原文地址:https://www.cnblogs.com/terrymin/p/14550425.html
Copyright © 2011-2022 走看看