手写Promise - 实现一个基础的Promise

前端开发中经常会用到Promise,不过有部分人并不清楚Promise的原理,本文也是本人在学习Promise时对Promis的一些认识,希望能对各位童鞋有所帮助。

手写Promise - 实现一个基础的Promise
手写Promise - 实例方法catch、finally
手写Promise - 常用静态方法all、resolve、reject、race

从认识Promise开始。。。

/* 模拟一个简单的异步行为 */
function fetchData() {
   
	return new Promise((resolve, reject) => {
   
		setTimeout(() => {
   
			resolve('willem');
		}, 1000);
	});
}

fetchData().then((data) => {
   
	// after 1000ms
	console.log(data); // willem
	return 'wei';
}, (err) => {
   }).then((data2) => {
   
	console.log(data2); // wei
});

上面的例子算是一个最常见的用法,可能在使用的时候更多的使用的是catch来处理异常来替代then方法的第二个参数,但catch也只是一个then的语法糖。

从中我们可以用一些句子来描述Promise。

  1. promise是一个类,它的构造函数接受一个函数,函数的两个参数也都是函数
  2. 在传入的函数中执行resolve表示成功,执行reject表示失败,传入的值会传给then方法的回调函数
  3. promise有一个叫做then的方法,该方法有两个参数,第一个参数是成功之后执行的回调函数,第二个参数是失败之后执行的回调函数。then方法在resolve或者reject执行之后才会执行,并且then方法中的值是传给resolve或reject的参数
  4. promise支持链式调用

有了相应的描述,接下来就是来一步一步实现了。

简单版Promise

1. promise是一个类,它的构造函数接受一个函数,函数的两个参数也都是函数

第一点比较简单

// 这里没有使用Promise作为类名是为了方便测试
class WPromise {
   
	constructor(executor) {
   
		// 这里绑定this是为了防止执行时this的指向改变,this的指向问题,这里不过多赘述
		executor(this._resolve.bind(this), this._reject.bind(this));
	}
	
	_resolve() {
   }
	
	_reject() {
   }
}

2. 在传入的函数中执行resolve表示成功,执行reject表示失败,传入的值会传给then方法的回调函数

成功、失败,这个很容易想到使用一个状态进行标记,实际上Promise就是这样做的。在Promise中使用了pending、fulfilled、rejected来标识当前的状态。

  • pending 初始状态,既不是成功,也不是失败状态。等待resolve或者reject调用更新状态。
  • fulfilled 意味着操作成功完成。
  • rejected 意味着操作失败。

需要注意的一点是,这三个状态之间只存在两个变换关系:

  • pending转换为fulfilled,只能由resolve方法完成转换
  • pending转换为rejected,只能由reject方法完成转换

传入的值会传给then的回调函数,怎么传递呢?显然我们将对resolve和reject的值做一个保存。

将上面的状态和值添加到Promise

class WPromise {
   
	static pending = 'pending';
	static fulfilled = 'fulfilled';
	static rejected = 'rejected';

	constructor(executor) {
   
		this.status = WPromise.pending; // 初始化状态为pending
		this.value = undefined; // 存储 this._resolve 即操作成功 返回的值
		this.reason = undefined; // 存储 this._reject 即操作失败 返回的值
		executor(this._resolve.bind(this), this._reject.bind(this));
	}
	
	_resolve(value) {
   
		this.value = value;
		this.status = WPromise.fulfilled; // 将状态设置为成功
	}
	
	_reject(reason) {
   
		this.reason = reason;
		this.status = WPromise.rejected; // 将状态设置为失败
	}
}

3. Promise有一个叫做then的方法,该方法有两个参数,第一个参数是成功之后执行的回调函数,第二个参数是失败之后执行的回调函数。then方法在resolve或者reject执行之后才会执行,并且then方法中的值是传给resolve或reject的参数

这句话有点长,需要注意的是这句then方法在resolve或者reject执行之后才会执行,我们知道Promise是异步的,也就是说then传入的函数是不能立马执行,需要存储起来,在resolve函数执行之后才拿出来执行。

换句话说,这个过程有点类似于发布订阅者模式:我们使用then来注册事件,那什么时候来通知这些事件是否执行呢?答案就是在resolve方法执行或者reject方法执行时。

ok, 继续完善我们的代码。

class WPromise {
   
    static pending = "pending";
    static fulfilled = "fulfilled";
    static rejected = "rejected";

    constructor(executor) 
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值