深度解析Promise(二)

本文深入解析Promise的实现逻辑,包括状态变迁、then方法的微任务机制、链式调用及catch方法。通过模拟异步操作,阐述如何创建并管理Promise状态,确保回调函数在正确的时间执行。同时,探讨了thenable对象作为Promise通用性的概念。
摘要由CSDN通过智能技术生成

分析一下实现Promise需要哪些逻辑

  • Promise有三种状态,pending(进行中)、fulfilled(已完成)、reject(已失败),外界无法改变其状态,且一旦状态改变就不会再变了
  • 实例化一个 Promise 需要传入一个 executor 函数 ,业务代码在 executor 函数中执行,另外 executor 函数接收两个参数 resolve 和 reject。resolve 和 reject 是 Promise 构造函数的内置函数
new Promise((resolve,reject)=>{
	// do something
})
  • 在 executor 函数中业务代码执行成功了,调用 resolve 函数,把 Promise 的状态变为已成功,另外通过参数把业务代码的执行成功的结果传递到 Promise 中
  • 在 executor 函数中业务代码执行失败了,调用 reject 函数,把 Promise 的状态变为已失败,另外通过参数把业务代码的执行失败的原因传递到 Promise 中
  • 实例方法 then 的第一个参数是业务代码执行成功的回调函数,第二个参数是业务代码执行失败的回调函数,当业务代码执行完毕后,会根据执行结果调用对应的回调函数,且这些回调函数接收业务代码的执行结果作为参数
  • then方法可以链式调用,具有穿透性
  • 实例方法 catch 来添加业务代码执行失败的回调函数

那么下面就一一来实现 Promise 的功能

初步搭建

根据分析,首先我们需要完成这些功能:

  • Promise 构造函数接收 executor 函数作为参数,且在其中执行 executor 函数

  • Promise 构造函数中有 resolve 和 reject 内置方法,并作为参数传递给 executor 函数

  • 设置个实例属性 status 来存储状态

  • 内置函数 resolve 可以把状态变为已成功,内置函数 reject 可以把状态变为已失败,且一旦状态改变就不会再变

// 这里使用了Symbol是为了防止外界其他原因改变了状态
const Pending = Symbol('Pending');
const Fulfilled = Symbol('Fulfilled');
const Rejected= Symbol('Rejected');

function Promise(excutor){
	// 初始状态为pending
	this.status = Pending;
	const resolve = () => {  // 这里为了this的指向,使用了箭头函数,如果不用箭头函数,需要用变量存一下this
		if(this.status === Pending){  // 只有在状态为pending时才可以发生改变
			this.status = Fulfilled;
		}
	};
	const reject = () => {
		if(this.status === Pending){  // 只有在状态为pending时才可以发生改变
			this.status = Rejected;
		}
	};
	excutor(resolve,reject);
}

初步实现then方法

按照上面对 then 实例方法的业务场景的简单分析,在 then 实例方法中调用回调函数时,还要把 executor 函数中业务代码的执行结果作为参数传递进去,那么要新增实例属性来存储业务代码的执行结果。另外执行成功的结果通过内置方法 resolve 的参数传入,其执行失败的原因通过内置方法 reject 的参数传入

因为then方法是实例可调用的,所以then方法是在构造函数原型上的:

// 这里使用了Symbol是为了防止外界其他原因改变了状态
const Pending = Symbol('Pending');
const Fulfilled = Symbol('Fulfilled');
const Rejected= Symbol('Rejected');

function Promise(excutor){
	// 初始状态为pending
	this.status = Pending;
	this.value = undefined;
	this.error = undefined;
	const resolve = value => {  // 这里为了this的指向,使用了箭头函数,如果不用箭头函数,需要用变量存一下this
		if(this.status === Pending){  // 只有在状态为pending时才可以发生改变
			this.status = Fulfilled;
			this.value = value;
		}
	};
	const reject = value => {
		if(this.status === Pending){  // 只有在状态为pending时才可以发生改变
			this.status = Rejected;
			this.error = value;
		}
	};
	excutor(resolve,reject);
};

Promise.prototype.then = function(resolveCallback,rejectCallback){  // 这里为什么不用箭头函数,注意this指向
	if(this.status === Fulfilled){
		if(resolveCallback && typeof resolveCallback === 'function'){
			resolveCallback(this.value);
		}
	}
	if(this.status === Rejected){
		if(rejectCallback && typeof rejectCallback === 'function'){
			rejectCallback(this.error);
		}
	}
}

初步实现了then方法,那么我来验证一下ÿ

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值