对实现Promise A+规范的polyfill 的讲解

本文详细讲解了Promise A+规范,特别是Promise声明时的运行过程和.then链式回调的执行逻辑。通过实例解析了简单和复杂解决过程,以及then方法的调用时机和返回规则,帮助理解Promise的工作原理。
摘要由CSDN通过智能技术生成

Promise A+ 规范


本篇仅讲述Promise声明时的运行过程和.then链式回调


声明时运行过程

Promise 解决过程

Promise 解决过程是一个抽象的操作,其需输入一个 promise 和一个值,我们表示为 [[Resolve]](promise, x),如果 x 有 then 方法且看上去像一个 Promise ,解决程序即尝试使 promise 接受 x 的状态;否则其用 x 的值来执行 promise 。

这种 thenable 的特性使得 Promise 的实现更具有通用性:只要其暴露出一个遵循 Promise/A+ 协议的 then 方法即可;这同时也使遵循 Promise/A+ 规范的实现可以与那些不太规范但可用的实现能良好共存。

运行 [[Resolve]](promise, x) 需遵循以下步骤:

x 与 promise 相等

如果 promise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 promise

x 为 Promise

如果 x 为 Promise ,则使 promise 接受 x 的状态 注4:

如果 x 处于等待态, promise 需保持为等待态直至 x 被执行或拒绝

如果 x 处于执行态,用相同的值执行 promise

如果 x 处于拒绝态,用相同的据因拒绝 promise

x 为对象或函数

如果 x 为对象或者函数:

把 x.then 赋值给 then 注5

如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise

如果 then 是函数,将 x 作为函数的作用域 this 调用之。传递两个回调函数作为参数,第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromise:

如果 resolvePromise 以值 y 为参数被调用,则运行 [[Resolve]](promise, y)

如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise

如果 resolvePromise 和 rejectPromise 均被调用,或者被同一参数调用了多次,则优先采用首次调用并忽略剩下的调用

如果调用 then 方法抛出了异常 e:

如果 resolvePromise 或 rejectPromise 已经被调用,则忽略之

否则以 e 为据因拒绝 promise

如果 then 不是函数,以 x 为参数执行 promise

如果 x 不为对象或者函数,以 x 为参数执行 promise

如果一个 promise 被一个循环的 thenable 链中的对象解决,而 [[Resolve]](promise, thenable) 的递归性质又使得其被再次调用,根据上述的算法将会陷入无限递归之中。算法虽不强制要求,但也鼓励施者检测这样的递归是否存在,若检测到存在则以一个可识别的 TypeError 为据因来拒绝 promise 注6。

大白话解释:

let p = new Promise((res,rej)=>{

res(1);

});

//这部分就是用户自定义的执行方法

(res,rej)=>{

res(1); //这就是解决过程

}

1即为x;

这个时候,x==1;

执行后面的方法

[[Resolve]](p, 1) // 注:[[Resolve]]这个写法类似obj-c

如果 x 有 then 方法且看上去像一个 Promise ,解决程序即尝试使 promise 接受 x 的状态;否则其用 x 的值来执行
promise 。

很明显,这时候x没有then方法,所以用 x 的值来执行p;

p这时候的value就是x;

p的state就是resolve,因为是执行了res的解决过程

--------------------------------------------欢乐模式----------------------------------------

简单的解决过程

let p = new Promise2((res,rej)=>{
   
		res(1);
})
p.then(console.log);

Promise2源码

const PENDING=Symbol();
const FULFILLED=Symbol();
const REJECTED=Symbol();
var Promise2 = function(func){
   
	this.value=null;
  this.state=PENDING;
  this.res_then=null;
  this.rej_then=null;
  
  goSafeResolveThen(this,func);
};
Promise2.prototype.then = function(res,rej){
   
	if(this.state===PENDING){
   
  	this.res_then=res;
    this.rej_then=rej;
  }else{
   
  	let resolver=this.state===FULFILLED? res : rej;
		resolver(this.value);
  }
}
function goSafeResolveThen(self,func){
   
	func(
      function(value){
   
        doResolve(self,value);
      },
      null  //不考虑失败
    )
}
function doResolve(self,value){
   
   
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值