Promise内部实现的原理

第一明确Promise是干什么用的

promise用来实现一步操作,解决了回调地狱的问题
所谓的promise简单来说就是一个容器,里面保存着某些未来才结束的事件(通常是一个异步操作)的结果。
从语法上来讲,Promise是一个对象,从它可以获取一步操作的消息。Promise对象的状态不受外部影响。
promise上面的方法

Promise.all()
Promise.race()
Promise.resolve()
Promise.reject()
Promise.prototype.catch()
Promise.prototype.finally()
Promise.prototype.then()

Promise.prototype.catch()方法是.then(null,rejection)的别名。用于指定发生错误时的回调函数

第二解析一下Promise的实现原理(源码)

const PENDING = 'pending'; //初始状态
const FULFILLED = 'fulfilled'; // 成功状态
const REJECTED = 'rejected'; // 成功
function Promise(extutor){
  let self = this;
  self.status = PENDING; // 设置状态
  // 存放成功回调的数组
  self.onResolveCallbacks = [];
  // 存放失败回调的数组
  self.onRejectedCallbacks = [];
  function resolve(value){
    if(self.status === PENDING){
      self.status = FULFILLED;
      self.value = value;
      self.onResolveCallbacks.forEach(cb => cd(self.value))
    }
  } 
  function reject(reason){
    if(self.status === PENDING){
      self.status = REJECTED;
      self.value = reason;
      self.onRejectCallbacks.forEach(cb => cd(self.value))
    }
  } 
  try{
    excutor(resolve, reject)
  } catch(e) {
    reject(e)
  }
}

then方法在调用then方法中传进去的时候是两个函数,分别对应的是promise中的一步方法成功和失败的回调

Promise.prototype.then = function(onFulfilled, onRejected){
  // 如果成功和失败的回调没有传,表示这个then没有任何逻辑,只负责把值往后抛
  onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : value => value
  onRejected = typeof onRejected == 'function' ? onRejected : reason => { throw reason }
  let self = this;
  let promise2;
  // 实现链式调用,每一种状态都要返回的是一个promise实例
  if(self.status == FULFILLED){ // 如果promise状态已经是成功态,onFulfilled直接取值
    return  promise2 = new Promise(function(resolve, reject){
      setTimeout(function(){  // 保证返回的promise是异步
        try{
          onFulfilled(self.value)
        } catch (e){
          //  如果执行成功的回调过程中出错,用错误原因把promise2 reject
          reject(e)
        }
      })
    })
  }
  if( self.status == REJECTED){
    return promise2 = new Promise(function(){
      setTimeout(function(){
        try{
          onFulfilled(self.value)
        } catch (e){
          reject(e)
        }
      })
    })
  }
  if(self.status === PENDING){
    return promise2 = new Promise(function(resolve, reject){
      // pending 状态时就会把所有的回调函数都添加到实例中的两个堆栈中暂存,等状态改变后依次执行,其实这个过程就是观察者模式
      self.onResolveCallbacks.push(function(){
        setTimeOut(function(){
          try{
            onFulfilled(self.value)
          } catch(e){
            reject(e)
          }
        })
      })
    })
    self.onRejectCallbacks.push(){
      setTimeOut(function(){
        try{
          onRejected(self.value)
        } catch(e){
          reject(e)
        }
      })
    }
  }
}

// 写到这,我也知识理解的一部分

以上只是支持一次then的调用,现实中我们会有这种需求

const p = new Promise(function(resolve, reject){
  if(/*异步操作的成功*/){
    resolve(value)
  } else {
    reject(error)
  }
});
p.then(function(){
}).then(function(){
}).then(function(){
}).catch(function(e){
  // failure
})

这种连续的调用返回promise实例的情况,而且我们要兼容then方法里返回的不是promise对象,这要求对then优化,加入一个解析promise的方法resolvePromise
三种情况:

  • 返回值是promise实例
  • 返回值是一个thenable对象或者函数
  • 没有返回值或者只返回一个普通值
const thenable = {
  // 具有then属性,而且属性值是如下格式的函数的对象  
then
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • title: promise总结 总结在前 前言 下文类似 Promise#then、Promise#resolv...
    JyLie阅读 14,204评论 1 21
  • 本文适用的读者 本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,...
    HZ充电大喵阅读 12,040评论 6 19
  • Promise 对象 Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函...
    neromous阅读 12,773评论 1 56
  • 你不知道JS:异步 第三章:Promises 在第二章,我们指出了采用回调来表达异步和管理并发时的两种主要不足:缺...
    purple_force阅读 6,330评论 0 4
  • 昏黄的灯盏下你轻轻吟唱 落日旁 你慢慢走回家乡 你怕你把故事写的太长 你怕你有太多不能忘 没关系一切人的宿命都有终...
    翔于阅读 3,060评论 1 3