Promise封装,一行一注释

485 阅读2分钟

HTML

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta http-equiv="X-UA-Compatible" content="IE=edge" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0" />
		<title>Document</title>
		<!-- 引入我们自己封装的Promise文件,文件定义里面 Promise,这时系统自带的Promise失效-->
		<script src="./myPromise.js"></script>
	</head>
	<body></body>
	<script>
		const p = new Promise((resolve, reject) => {
			// 同步函数resolve
			// resolve('ok1')

			// 同步函数reject
			// reject('err')

			// 异步函数测试
			// setTimeout(() => {
				// 异步函数resolve
				// resolve('ok')
				// 异步函数reject
				// resolve('error')
			// }, 1000)
		})
		// 链式调用
		const res = p.then(
			// resolve回调
			value => {
				// resolve('ok') 则value输出ok
				// console.log(value)

				// 返回另外一个Promise对象
				// return new Promise((resolve, reject) => {
					// promise执行异步函数
					// setTimeout(() => {
					// 	resolve('promise ok')
					// 	console.log(value)
					// }, 1000)
				// })
				// 执行resolve()错误抛出
				// throw "FAIL1"
			},
			// reject回调
			reason => {
				// reject('err') 则reason输出err
				// console.log(reason)

				// 执行reject()错误抛出
				// throw "FAIL2"
			}
		)
		// 输出res 查看Premise状态
		console.log(res)
	</script>
</html>

JavaScript

// 封装Promise

// 声明构造函数
// 注:这里声明的函数会直接把系统的Promise函数覆盖
function Promise(executor) {
	// 状态开始为pending
	this.PromiseState = 'pending'
	// 返回值开始为null
	this.PromiseResult = null
	// 声明属性,保存回调函数
	this.callback = []

	// 锁定this,这里this指向Promise对象
	// 参考:如果是在new中调用,this则为新创建的对象
	// 若resolve/reject为箭头函数,此处可省略
	const _this = this
	// resolve函数
	function resolve(data) {
		// 状态改变,则不可逆
		if (_this.PromiseState !== 'pending') return
		// 改变pending状态为resolved
		_this.PromiseState = 'resolved'
		// 传入data
		_this.PromiseResult = data
		// 这里对应then函数 如果Promise传入的是一个异步代码
		// 那么PromiseState就是一个pending状态
		// 所以要再次执行调用Promise,直到PromiseState为resolved或者resolved为止
		// 这里传入data用于下一次执行Promise的传参
		_this.callback.forEach(item => {
			item.onResolved(data)
		})
	}
	// reject函数
	function reject(data) {
		// 状态改变,则不可逆
		if (_this.PromiseState !== 'pending') return
		// 改变pending状态为rejected
		_this.PromiseState = 'rejected'
		// 传入data
		_this.PromiseResult = data

		_this.callback.forEach(item => {
			item.onRejected(data)
		})
	}
	// 抛出异常处理
	try {
		// 同步调用execltor
		execltor(resolve, reject)
	} catch (error) {
		// 修改promise对象状态为失败
		reject(error)
	}
}
// 核心:then函数 传入成功会执行的代码和失败会执行的代码
Promise.prototype.then = function (onResolved, onRejected) {
	// 返回Promise对象 用于链式调用
	return new Promise((resolve, reject) => {
		// 封装函数 用于状态为resolved时或rejected时执行
		// type 当状态为resolved则为onResolved(this.PromiseResult)
		//      当状态为rejected则为onRejected(this.PromiseResult)
		// handle函数作用:判断是否是Promise对象,如果不是,改变状态,传出结果
		// 如果是,继续调用then 另捕捉throw传出的错误且改变状态
		const handle = type => {
			// 错误处理 用于捕捉throw 'FAIL'
			try {
				// 执行成功/失败会执行的函数
				let result = type(this.PromiseResult)
				// 若返回值为Promise对象,则继续递归执行then
				if (result instanceof Promise) {
					// 链式调用then,传入成功和失败代码片段
					result.then(
						v => {
							resolve(v)
						},
						r => {
							reject(r)
						}
					)
				} else {
					// 如果不是Promise对象,改变状态,传出result
					resolve(result)
				}
			} catch (error) {
				// 如果是throw,直接失败,传出抛出的error
				reject(error)
			}
		}
		// 调用回调函数
		// 如果状态为resolved
		if (this.PromiseState === 'resolved') {
			// 使用handle改变状态 确定结果
			handle(onResolved)
		}
		// 如果状态为rejected
		if (this.PromiseState === 'rejected') {
			// 使用handle改变状态 确定结果
			handle(onRejected)
		}
		// 如果状态为pending
		// 代表着Promise里面传入的为异步函数
		if (this.PromiseState === 'pending') {
			// 将需要执行的异步函数存入callback数组
			// 当异步函数结束,调用resolve / reject时,对应上面this.callback.forEach执行
			this.callback.push({
				onResolved: () => {
					handle(onResolved)
				},
				onRejected: () => {
					handle(onRejected)
				},
			})
		}
	})
}