Promise

67 阅读4分钟

Promise

Promise 用于表示一个异步操作的最终完成(或失败)及其结果值。

  • Promise 必然处于以下下状态

    1. pending:待定
    2. fulfilled:已完成(已兑现)
    3. rejected:已失败
  • 一个pending状态的Promise要么通过一个值被兑现fulfilled,要么通过一个原因(错误)被拒绝rejected

  • Promise的链式调用,如 thencatch等方法返回promise

实现一个Promise

  • 基本的Promise

    1. Promise通过接受一个回调函数,此回调函数有两个参数:resolverejectresolve表示成功的回调,reject表示失败的回调
    2. Promise内部维持着一个status用来存储当前promise对象的状态
    3. 通过valuereason存储成功或失败的原因
    4. 处于pending状态的promise则保存它的then函数的回调,存在callbacks中,onResolved保存成功的回调,onRejected保存失败的回调
    5. 只有处于pending状态的promise才能变更为fulfilledrejected
    6. 使用setTimeout模拟异步
      class MyPromise {
          static PENDING = 'pending'
          static FULFILLED = 'fulfilled'
          static REJECTED = 'rejected'
          constructor(executor){
              this.status = MyPromise.PENDING
              this.value = undefined
              this.reason = undefined
              this.callbacks = []
              const resolve = (value) => {
                  if(this.status === MyPromise.PENDING){
                      setTimeout(()=>{
                          if(this.status !== MyPromise.PENDING) return
                          this.statue = MyPromise.FULFILLED
                          this.value = value
                          this.callbacks.forEach(fns=>{
                              fns.onResolved(value)
                          })
                      })
                  }
              }
              const reject = (reason) => {
                  if(this.status === MyPromise.PENDING){
                      setTimeout(()=>{
                          if(this.status !== MyPromise.PENDING) return
                          this.statue = MyPromise.REJECTED
                          this.reason = reason
                          this.callbacks.forEach(fns=>{
                              fns.onRejected(reason)
                          })
                      })
                  }
              }
              // 同步执行此回调
              try {
                  executor(resolve, reject)
              } catch(error) {
                  // 捕获错误
                  reject(error)
              }
          }
      }
      
  • then方法

    1. then方法有两个参数:onResolvedonRejected回调函数
    2. 变更后的状态不能再改变
    3. 返回值为一个promise对象,并返回其值
    4. 定义一个函数用来检测是否发生异常execFunctionWithCatchError,出现异常则执行reject,否则执行resolve
      • 判断是否是thenable对象(实现了then方法的对象)
    
    
    function execFunctionWithCatchError(execFns, value, resolve,reject){
    	try{
    		// 执行回调函数,得到其结果
    		const result = execFns(value)
    		// 判断是否是promise或thenable对象
    		if(result instanceof MyPromise || (result.then && typeof result.then === 'function'))
    		{
    			result.then(resolve, reject)
    		}else { resolve(result) }
    	} catch(error) {
    		reject(error)
    	}
    }
    class MyPromise {
    	/* ... */
    	then(onResolved, onRejected) {
    		onResolved = typeof onResolved === 'function' ? onResolved : value=>value
    		onRejected = typeof onRejected === 'function' ? onRejected : reason=>reason
    		return  new MyPromise((resolve, reject) => {
    			if(this.status === MyPromise.PENDING) {
    				// 将回调存储
    				this.callbacks.push({
    					onResolved: () => { execFunctionWithCatchError(onResolved, this.value, resolve, reject) }
    					onRejected: () => { execFunctionWithCatchError(onRejected, this.reason, resolve, reject) }
    				})
    			}
    			if(this.status === MyPromise.FULFILLED) {
    				// 执行onResolved
    				execFunctionWithCatchError(onResolved, this.value, resolve, reject)
    			}
    			if(this.status === MyPromise.REJECTED) {
    				// 执行onRejected
    				execFunctionWithCatchError(onRejected, this.reason, resolve, reject)s
    			}
    		})
    
    	}
    }
    
  • catch方法

    • 用来处理异常,
    class MyPromise {
    	/* ... */
    	catch(onRejected){
        	return this.then(undefined, onRejected)
    	}
    }
    
  • finally方法

    • promise无论成功还是失败都会执行的回调
    class MyPromise {
    	/* ... */
    	finally(onFinally){
        	this.then(onFinally, onFinally)
    	}
    }
    
  • resolve类方法

    • 接受一个参数,返回已兑现fulfilled状态的promise对象
      • 如果参数为Promise或thenable对象,则直接返回此参数
    class MyPromise {
        static resolve(value){
    		return new MyPromise((resolve, reject)=>{
    			if(value instanceof MyPromise || (value.then && typeof value.then === 'function'))
    			{ value.then(resolve, reject) 
    			}else { resolve(value) }
    		})
        }	
    }
    
  • reject类方法

    • 接受一个参数,返回已失败rejected状态的promise对象
    class MyPromise {
        static resolve(value){
    		return new MyPromise((resolve, reject)=>{
    			reject(value)
    		})
        }	
    }
    
  • all类方法

    • 参数:一个可迭代对象
    • 返回值:
      1. 空的可迭代对象,返回fulfilled状态的promise
      2. 参数中不包含任何promise则返回fulfilled状态的promise
      3. 其他情况:返回一个pending状态的promise对象,
        • 如果参数中有一个失败的promise则将其作为参数返回失败状态的promise,不管其他promise是否完成
        • 返回成功的promise,参数为所有成功的 resolve 回调结果的数组
    class MyPromise {
        static all(promises){
    		if(promises.length === 0) { return MyPromise.resolve() }
    		return new MyPromise((resolve, reject) => {
    			const result = []
    			promises.forEach(promise => {
    				const p = promise instanceof MyPromise ? promise : MyPromise.resolve(promise)
                    p.then(
                        res => {
                            result.push(res)
                            if(result.length === promises.length) { resolve(result) } 
                        },
                        err => { reject(err) }
                    )
    			})
    		})
        }	
    }
    
  • allSettled类方法

    • 参数:一个以 promise 组成的可迭代iterable对象
    • 返回值:
      1. 空的iterable,返回fulfilled状态的promise

      2. iterable中所有的promise已敲定,兑现为一个数组,按照iterable的传递顺序返回,数组中通过对象描述该promise

      • status "fulfilled" | "rejected"

      • value 为"fulfilled"才存在。在 promise 兑现时返回 value

      • reason 为"rejected"才存在。在 promise 拒绝时返回 reason

      class MyPromise {
      	allSettled(promises){
      		const result = []
      		promises.forEach(promise => {
      			const p = promise instanceof MyPromise ? promise : MyPromise.resolve(promise)
      			p.then(
      				res => { result.push({statue: MyPromise.FULFILLED, value: res})},
      				err => { result.push({statue: MyPromise.REJECTED, reason: err})}
      			)
      		})
        		return MyPromise.resolve(result)
        	}
        }
    
  • race类方法

    • 返回一个 promise,一旦迭代器中的某个 promise 解决或拒绝,返回的 promise 就会解决或拒绝。
    • 参数为:一个可迭代对象
    class MyPromise {
    	race(promises){
    		return new MyPromise((resolve, reject) => {
    			promises.forEach(promise => {
    				const p = promise instanceof MyPromise ? promise:MyPromise.resolve(promise)
    				p.then(
    					res => { resolve(res) },
    					err => { reject(err) }
    				)
    			})
    		})
    	}
    }
    
  • any类方法

    • 参数为:一个可迭代对象
    • 返回值:
      1. 空的可迭代对象,返回拒绝的promise
      2. 可迭代对象中的任意一个 promise 兑现了,那么这个处于等待状态的 promise 就会异步地(调用栈为空时)切换至兑现状态;可迭代对象中所有的promise都被拒绝了则处于等待状态的 promise 就会异步地切换至被拒状态,并且原因是 AggregateError 实例(Error的子类)
    class MyPromise {
    	any(promises){
    		return new MyPromise((resolve, reject) => {
    			const result = []
    			promises.forEach(promise => {
    				const p = promise instanceof MyPromise ? promise : MyPromise.resolve(promise)
    				p.then(
    					res => { resolve(res) },
    					err => { 
                        	result.push(err)
                        	if(result.length === promises.length){
                        		reject(new AggregateError(result))
                        	}
                        }    					
    				)
    			})
    		} )
    	}
    }