• 手写符合Promise/A+规范的Promise


    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)
    })
    

      

  • 相关阅读:
    关于PHP写的投票网站之刷票风云
    《暗战强人:黑客及反黑客工具快速精通》学习笔记
    《Linux信息安全实用教程》学习笔记
    MySql的入侵测试以及防范
    基于Sql Server 2008的分布式数据库的实践(终结)
    Sql Server的弱口令入侵测试以及防范
    IPC$ 测试与防范
    基于Sql Server 2008的分布式数据库的实践(五)
    基于Sql Server 2008的分布式数据库的实践(四)
    基于Sql Server 2008的分布式数据库的实践(三)
  • 原文地址:https://www.cnblogs.com/gwf93/p/10418501.html
Copyright © 2020-2023  润新知