promise的实现(如何手写一个promise)

6 篇文章 0 订阅

如果你打算手动实现一个promise,你可能需要先问问自己,promise是什么?你平常最常见的promise是怎么样用的?

new Promise((resolve,reject)=>{
	resolve(2)
}).then(val=>{
	console.log(val)
})

在这里插入图片描述
如果你了解事件循环,你就知道,promise里面的回调函数是在立即执行的,而then中的回调任务是会被推入异步微队列中等待执行的。

让我们先来捋捋这个Promise到底是个什么?
Promise是异步函数的一种写法,通过new Promise 创建一个promise对象。promise一种有三种状态:

  • pending
  • fulfilled
  • rejected

初始时,状态都是pending,如果调用了resolve函数,那么这个promise的状态就会变成 fulfilled, 状态一经变更,就再也不能改变了。同样,如果调用了reject函数,promise的状态就会由pending变为rejected. 通过以上的这些信息,我们先来实现一部分Promise的功能。

class Promise{
	constructor(executor){
		this.state = 'pending'
		this.value = undefined
		this.reason = undefined
		let resolve = value=>{
			if(this.state === 'pending'){
				this.value = value
				this.state = 'fulfilled'
			}
		}
		let reject = reason=>{
			if(this.state === 'pending'){
				this.reason = reason
				this.state = 'rejected'
			}
		}
		
		try{
			executor(resolve,reject)  // 立即执行的,执行出错的话,reject
		}catch(err){
			reject(err)
		}

	}
	then(onFulfilled,onRejected){
		if(this.state === 'fulfilled'){
			onFulfilled(this.value)
		}
		if(this.state === 'rejected'){
			onRejected(this.reason)
		}
	}	
}

如果我们在setTimeout的回调函数里调用resolve呢?
在这里插入图片描述
这时候还使用上述我们自己写的Promise就打印不出来4了,这是为什么呢?

这是因为,在执行executor时,遇到了setTimeout,等待400s后将它的回调()=>{resolve(4)} 推入到异步宏队列中等待空闲执行。接着将.then中的回调推入异步微队列中等待空闲执行。这时候主执行栈空闲, 它会先取出微队列的回调函数执行,执行时,由于this.state还是pending,因此啥也没打印,接着再取出宏任务,resolve(4) 。结果就是啥也没打印。因此我们优化一下代码。

class Promise{
	constructor(executor){
		this.state = 'pending'
		this.value = undefined
		this.reason = undefined
		this.fulfilledCallbacks = []
		this.rejectedCallbacks = []
		let resolve = value=>{
			if(this.state === 'pending'){
				this.value = value
				this.state = 'fulfilled'
				this.fulfilledCallbacks.forEach(callback =>{
					callback(value)
				})
			}
		}
		let reject = reason=>{
			if(this.state === 'pending'){
				this.reason = reason
				this.state = 'rejected'
				this.rejectedCallbacks.forEach(callback =>{
					callback(reason)
				})
			}
		}
		try{
			executor(resolve,reject)
		}catch(err){
			reject(err)
		}
	}
	then(onFulfilled,onRejected){
		if(this.state === 'pending'){
			this.fulfilledCallbacks.push(onFulfilled)
			this.rejectedCallbacks.push(onRejected)
		}
		if(this.state === 'fulfilled'){
			onFulfilled(this.value)
		}
		if(this.state === 'rejected'){
			onRejected(this.reason)
		}
	}
}

ok~ 测试了一下没有问题

promise还有很多其他功能,在下篇可以一一挖掘
promise的实现(如何手写一个promise)(下)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值