Promise源码实现

本文深入探讨了Promise A+规范,详细解释了Promise对象作为异步操作处理的核心,其必须是对象并且包含then方法的原理和应用场景。
摘要由CSDN通过智能技术生成

promise A+ 规范

必须是对象,且必须含有then方法

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
// 模拟微队列
function runMicroTask(callback) {
	if(process && process.nextTick) {
		process.nextTick(callback)
	} else if(MutationObserver) {
		const observer = new MutationObserver(callback)
		const p = document.createElement('p')
		observer.observe(p, {
			childList: true // 监听p的子元素,元素发生变化后运行回调
		}
		p.innerHTML = 1
	} else {
		setTimeout(callback, 0)
	}
}
//判断是否符合promise A+规范
function isPromise(obj) {
	return !!(obj && typeof obj === 'object' && typeof obj.then === 'function')
}
class MyPromise {
	constructor(handler) {
		if(typeof handler !== 'function') {
			throw TypeError('handler must be a function!')
		}
		this._status = PENDING
		this._value = undefined
		this._handlers = []  // 事件数组
		try {
			handler(this._resolve.bind(this), this._reject.bind(this))
		} catch(err) {
			this._reject(err)
		}
	}
	//将事件推入队列等待执行
	_pushHandler(executor, status, resolve, reject) {
		this._handlers.push({executor, status, resolve, reject})
	}
	// 将事件从队列中取出依次执行
	_runHandlers() {
		if(this._status === PENDING) return
		while(this._handlers[0]) {
			_runHandler(this._handlers[0])
			this._handlers.shift()
		}
	}
	// 执行某个事件
	_runHandler({ executor, status, resolve, reject }) {  // 将参数解构以防this指向问题
		runMicroTask(() => {
			if(this._status !== status) return
			if(typeof executor !== 'function') {
				this._status === FULFILLED ? resolve(this._value) : reject(this._value)
			}
			try {
				const result = executor(this._value)
				if(isPromise(result)) {
					result.then(resolve, reject)
				} else {
					resolve(result)
				}
			} catch(err) {
				reject(err)
			}
		})
		
	}
	_resolve(data) {
		if(this._status !== PENDING) {
			return
		}
		this._value = data
		this._status = FULFILLED
		this._runHandlers()  // 状态改变依次运行队列的函数
	}
	_reject(err) {
		if(this._status !== PENDING) {
			return
		}
		this._value = err
		this._status = REJECTED
		this._runHandlers()  // 状态改变依次运行队列的函数
	}
	then(onFulfilled, onRejected) {
		return new MyPromise((resolve, reject) => {
			this._pushHandlers(onFulfilled, FULFULLED, resolve, reject)
			this._pushHandlers(onRejected, REJECTED, resolve, reject)
			this._runHandlers()  // 状态改变依次运行队列的函数
		})
	}
	catch(onRejected) {
		return this.then(null, onRejected)
	}
	finally(onSettled) {
		return this.then((data) => {
			onSettled()
			return data
		}, (err) => {
			onSettled()
			throw err
		}}
	}

	// 静态方法
	static resolve(data) {
		if(data instaceof MyPromise) {
			return data
		}
		return new MyPromise((resolve, reject) => {
			if(isPromise(data)) {
				data.then(resolve, reject)
			} else {
				resolve(data)
			}
		})
	}
	static reject(err) {
		return new MyPromsie((resolve, reject) => {
			reject(err)
		})
	}
	static all(proms) {
		return new MyPromsie((resolve, reject) => {
			try {
				let results = []
				let count = 0
				let fulfilledCount = 0
				for(let p of proms) {
					let i = count;
					count++
					MyPromse.resolve(p).then(data => {
						fulfilledCount++
						results[i] = data
						if(count === fulfilledCount) {
							resolve(results)
						}
					}, reject)
				}
				if(count === 0) {  // 当数组长度为0时
					resolve(results)
				}
			} catch(err) {
				reject(err)
			}
			
		})
	}
	static allSettled(proms) {
		const arr = []
		for(const p of proms) {
			arr.push(MyPromsie.resolve(p).then(data => ({ value: data, status: FULFILLED}), err => ({ reason: err, status: REJECTED })))
		}
		return MyPromise.all(arr)
	}
	 static race(proms) {
	 	return new MyPromise((resolve, reject) => {
			for(const p of proms) {
	 			MyPromise.resolve(p).then(resolve, reject)
	 		}
		})
	 }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值