博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
手写符合Promise/A+规范的Promise
阅读量:4605 次
发布时间:2019-06-09

本文共 3332 字,大约阅读时间需要 11 分钟。

const PENDING = "pending";const RESOLVED = "resolved";const REJECTED = "rejected";function MyPromise(fn){	const that = this;	that.state = PENDING;	that.value = null;	that.resolvedCallbacks = [];	that.rejectedCallbacks = [];	function resolve(value){		// 判断传入的值是否为 Promise 类型		if( value instanceof MyPromise){			return value.then(resolve, reject)		}		// 为了保证函数的执行顺序,需要将两个函数体代码使用 setTimeout 包裹起来		setTimeout(()=>{			// 只有等待状态才可以改变状态			if(that.state == PENDING){				// 将当前状态更改为对应状态,并且将传入的值赋值给 value				that.state = RESOLVED;				that.value = value;				// 遍历回调数组并执行				that.resolvedCallbacks.map(cb => cb(that.value));			}		},0)			}	function reject(value){		setTimeout(()=>{			if(that.state == PENDING){				that.state == REJECTED;				that.value = value;				that.rejectedCallbacks.map( cb => cb(that.value));			}		})	}	try {		fn(resolve, reject)	} catch (e) {		reject(e)	}}MyPromise.prototype.then = function(onFulfilled, onRejected){	const that = this;	// 判断两个参数是否为函数类型, 这两个参数是可选参数	// 当参数不是函数类型时,需要创建一个函数赋值给对应的参数,同时也实现了透传	onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;	onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r};	if(that.state === PENDING){		// 返回了一个新的 Promise 对象,并在 Promise 中传入了一个函数		// 规范规定,执行 onFulfilled 或者 onRejected 函数时会返回一个 x,并且执行 Promise 解决过程,这是为了不同的 Promise 都可以兼容使用,比如 JQuery 的 Promise 能兼容 ES6 的 Promise		return (promise2 = new MyPromise((resolve, reject)=>{			that.resolvedCallbacks.push(()=>{				try {					const x = onFulfilled(that.value)					resolutionProcedure(promise2, x, resolve, reject)				}catch (r) {					reject(r)				}			});			that.rejectedCallbacks.push(()=>{				try {					const x = onRejected(that.value)					resolutionProcedure(promise2, x, resolve, reject)				} catch (r) {					reject(r)				}			});		}))	}	if(that.state === RESOLVED){		return (promise2 = new MyPromise((resolve, reject)=>{			setTimeout(()=>{				try {					const x = onFulfilled(that.value)					resolutionProcedure(promise2, x, resolve, reject)				} catch (reason) {					reject(r)				}			})		}))	}	if(that.state === REJECTED){		return (promise2 = new MyPromise((resolve, reject)=>{			try {				const x = onRejected(that.value);				resolutionProcedure(promise2, x, resolve, reject)			}catch(r){				reject(r)			}		}))	}	function resolutionProcedure(promise2, x, resolve, reject) {		if (promise2 === x) {			return reject(new TypeError('Error'))		}		if (x instanceof MyPromise) {			x.then(function(value) {					resolutionProcedure(promise2, value, resolve, reject)			}, reject)		}		// 创建一个变量 用于判断是否已经调用过函数	// 	let called = false;	// 	if (x !== null && (typeof x === 'object' || typeof x === 'function')) {	// 		try {	// 			let then = x.then	// 			if (typeof then === 'function') {	// 				then.call(	// 					x,	// 					y => {	// 						if (called) return	// 						called = true	// 						resolutionProcedure(promise2, y, resolve, reject)	// 					},	// 					e => {	// 						if (called) return	// 						called = true	// 						reject(e)	// 					}	// 				)	// 			} else {	// 				resolve(x)	// 			}	// 		} catch (e) {	// 			if (called) return	// 			called = true	// 			reject(e)	// 		}	// 	} else {	// 		resolve(x)	// 	}	}}// 创建一个实例 new MyPromise((resolve, reject) => {  setTimeout(() => {    resolve(1)  }, 0)}).then(value => {  console.log(value)})

  

转载于:https://www.cnblogs.com/gwf93/p/10418501.html

你可能感兴趣的文章
(文件过多时)删除目录下全部文件
查看>>
T-SQL函数总结
查看>>
python 序列:列表
查看>>
web移动端
查看>>
pythonchallenge闯关 第13题
查看>>
linux上很方便的上传下载文件工具rz和sz使用介绍
查看>>
React之特点及常见用法
查看>>
【WEB前端经验之谈】时间一年半,或沉淀、或从零开始。
查看>>
优云软件助阵GOPS·2017全球运维大会北京站
查看>>
linux 装mysql的方法和步骤
查看>>
poj3667(线段树区间合并&区间查询)
查看>>
51nod1241(连续上升子序列)
查看>>
SqlSerch 查找不到数据
查看>>
集合相关概念
查看>>
Memcache 统计分析!
查看>>
(Python第四天)字符串
查看>>
个人介绍
查看>>
使用python动态特性时,让pycharm自动补全
查看>>
MySQL数据库免安装版配置
查看>>
你必知必会的SQL面试题
查看>>