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

如果你打算手动实现一个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)(下)

好的,以下是一个简单的手写Promise实现: ```javascript class MyPromise { constructor(executor) { this.state = 'pending'; this.value = null; this.reason = null; this.onFulfilledCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onFulfilledCallbacks.forEach((callback) => callback(this.value)); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach((callback) => callback(this.reason)); } }; try { executor(resolve, reject); } catch (error) { reject(error); } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value; onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; }; const promise2 = new MyPromise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } else if (this.state === 'rejected') { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); } else { this.onFulfilledCallbacks.push(() => { setTimeout(() => { try { const x = onFulfilled(this.value); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { const x = onRejected(this.reason); this.resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); return promise2; } catch(onRejected) { return this.then(null, onRejected); } resolvePromise(promise2, x, resolve, reject) { if (promise2 === x) { reject(new TypeError('Chaining cycle detected')); } let called = false; if (x instanceof MyPromise) { x.then((value) => { this.resolvePromise(promise2, value, resolve, reject); }, (reason) => { if (!called) { called = true; reject(reason); } }); } else if (x !== null && (typeof x === 'object' || typeof x === 'function')) { try { const then = x.then; if (typeof then === 'function') { then.call(x, (value) => { if (!called) { called = true; this.resolvePromise(promise2, value, resolve, reject); } }, (reason) => { if (!called) { called = true; reject(reason); } }); } else { resolve(x); } } catch (error) { if (!called) { called = true; reject(error); } } } else { resolve(x); } } static resolve(value) { return new MyPromise((resolve) => { resolve(value); }); } static reject(reason) { return new MyPromise((resolve, reject) => { reject(reason); }); } static all(promises) { const results = []; return new MyPromise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { const promise = promises[i]; if (!(promise instanceof MyPromise)) { promise = MyPromise.resolve(promise); } promise.then((value) => { results[i] = value; if (results.length === promises.length) { resolve(results); } }, (reason) => { reject(reason); }); } }); } static race(promises) { return new MyPromise((resolve, reject) => { for (let i = 0; i < promises.length; i++) { const promise = promises[i]; if (!(promise instanceof MyPromise)) { promise = MyPromise.resolve(promise); } promise.then((value) => { resolve(value); }, (reason) => { reject(reason); }); } }); } } ``` 这个实现包含了Promise的基本功能,包括resolve、reject、then、catch、resolvePromise等方法,并且还实现Promise.all和Promise.race方法。但是这个实现并不完整,还有很多细节需要考虑和完善。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值