Promise的实现原理

大致思路

1、Promise的构造函数,只有一个函数参数resolver(resolve,reject),而函数参数resolver的两个参数都是函数参数,第一个参数resolve表示处理成功执行的函数,reject表示失败执行的函数

在构造函数中的属性有state(保存当前promise的状态);value(保存resolve或发生reject的错误原因);queue(Array,同一个promise可以多次调用then方法,这里是保存调用then方法之后生成的promise对象及其对应的resolve reject函数)

构造函数主要职责有:

a)初始化Promise的状态,this.state = PENDING

b)初始化resolve或reject的参数值,this.value = void 0

c)初始化then()注册的回调函数,this.queue = []

d)立即执行resolver(resolve,reject),即调用函数safelyResolveThen(self, then)-

立即执行resolver(resolve,reject)被封装在函数safelyResolveThen(self, then)----self为当前promise对象,resolver=then

这里就是执行函数resolver.

通过闭包对变量called的持有,使变量一直保存在内存中,达到resolve reject只执行一次,即同一个promise的状态由pending=>fulfilled或者pending => rejected只发生一次

在函数safelyResolveThen(self, then)里面调用了全局函数doResolve(self, value)和doReject(self, error)

doResolve(self, value)—doResolve 结合 safelyResolveThen 使用,不断地解包 promise 对象后,当值不是一个thenable对象时设置 promise 的状态和值。解包promise对象使用了方法getThen(value)。同时对queue遍历,通知queue中的每个promise的子promise,子promise 根据传入的值设置自己的状态和值

getThen(value)----如果value是一个thenable对象函数,那么就返回一个函数(在函数内,通过apply将value.then方法的作用域改成value,并执行then方法)

doReject(self, error) -----设置 promise的state为 REJECTED,value 为 error。同时遍历queue,对每个成员对象调用 callRejected,通知子 promise,子 promise 根据传入的错误设置自己的状态和值

2、Promise.prototype.then(onFulfilled, onRejected)----两个参数,成功时执行的回调函数onFulfilled,失败时执行的回调函数

onRejected。返回值是一个新生成的promise对象

根据当前promise的state状态来做相应的处理:

1)存在值穿透问题,即then方法没有参数或者参数为一个值

2)state不为PENDING,则执行unwrap(promise, resolver, this.value)。判断state为FULFILLED则resolver=onFulfilled,为REJECTED则resolver=onRejected。

3)否则promise的状态没有改变,即state=PENDIGN,将生成的promise对象和对应的onFulfilled, onRejected加入到当前promise的回调队列queue里面

unwrap(promise, resolver, this.value)----调用immediate.js将同步代码生成异步代码。同时执行回调函数,并验证处理的结果returnValue,如果为promise本身则抛出错误,否则调用doResolve(promise, returnValue)

Promise的静态方法

3、Promise.resolve(value)------返回一个promise对象;

a)value是一个promise对象则直接返回value;否则调用doResolve函数

b)value是一个thenable对象,将其转为promise对象,立即执行then方法,该promise的状态由这个thenable对象的then方法的具体设置而定;

c)value是一个原始值,或者是一个不具有then方法的对象,返回promise对象,状态为resolve

d)不带任何参数,直接返回一个promise对象

4、Promise.reject(reason)----返回一个promise对象;该实例的状态为rejected

直接返回doReject(promise, reason)处理后的结果

5、Promise.all(iterable)-------接受一个参数,返回一个promise。将多个promise封装成一个promise

返回promise的回调函数的参数值:

a)只有iterable中所有的promise对象的状态都变成fulfilled的时候,返回promise的状态才为fulfilled,且传递给返会promise对象的回调函数的参数为Array,元素由这些promise resolve之后的值组成

b)否则返回第一个被reject的实例的返回值,作为返回promise的回到函数的参数

6、Promise.race(iterable)-------接受一个参数,返回一个promise。将多个promise封装成一个promise

返回promise的回调函数的参数值:

a)返回第一个状态先改变的promise对象处理之后的值

'use strict';
 
var immediate = require('immediate');  //用immediate.js库将同步代码装成异步代码
 
function INTERNAL() {
   }
 
function isFunction(func) {
   
  return typeof func === 'function';
}
 
function isObject(obj) {
     //Array   Object  Null  Set   Map 都为true
  return typeof obj === 'object';   
}
 
function isArray(arr) {
   
  return Object.prototype.toString.call(arr) === '[object Array]';
}
 
var PENDING = 0;    //控制promise对象的状态
var FULFILLED = 1;
var REJECTED = 2;
 
module.exports = Promise;  //输出模块
 
function Promise(resolver) {
      //Promise构造函数
  if (!isFunction(resolver)) {
   
    throw new TypeError('resolver must be a function');
  }
  this.state = PENDING;  //初始化promise的状态为PENDIGN
  this.value = void 0;   //初始化resolve或reject的参数值
  this.queue = [];       //then方法可被同一个promise对象多次调用,用于注册新生成的promise对象
  if (resolver !== INTERNAL) {
     
    safelyResolveThen(this, resolver);  //立即执行传进来的resolver函数
  }
}
 
function safelyResolveThen(self, then) 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值