自己动手实现的promise
发布于 6 年前 作者 fuxingZhang 2959 次浏览 来自 分享

看了很多promise的实现,比如这里: 1、http://coderlt.coding.me/2016/12/04/promise-in-depth-an-introduction-2/ 2、https://zhuanlan.zhihu.com/p/25178630 感觉很绕,不符合自己的思维习惯,所以想自己动手写一个

在谷歌浏览测试各种情况、错误,看谷歌浏览器是如何反馈的,来改进自己的代码 image.png 所以函数名是resolver(只是为了让表现行为更接近chrome),需要的代码是:if(typeof resolver !== ‘function’) throw new TypeError(Promise resolver ${resolver} is not a function); 。。。。。。

源码: https://github.com/fuxingZhang/promiseImplementing 还在更新中。。。。 If you like, please help me improve the code

code :

function Promise(resolver){
	if(typeof resolver !== 'function') {
		throw new TypeError(`Promise resolver ${resolver} is not a function`)
	}
	this.state = 'pending'
	this.value = void 0
	try{
		resolver(this.resolve.bind(this), this.reject.bind(this))
	}catch(error){
		this.reject.call(this,error)
	}
}

Promise.prototype.resolve = function(value) {
	if(this.state !== 'pending') return
	this.value = value
	this.state = 'fulfilled'	
	setTimeout( () => {
		if(!this.onFulfilled) return
		this.onFulfilled(value)
	}, 0)
};

Promise.prototype.reject = function(reason){
	if(this.state !== 'pending') return
	this.value = reason
	this.state = 'rejected'
	setTimeout( () => {
		if(this.onRejected){
			this.onRejected(reason)
		}else{
			throw `Uncaught (in promise) ${reason}`
		}
	}, 0)
};

Promise.prototype.then = function(fulfilled, rejected){
	if ( typeof fulfilled !== 'function' && typeof rejected !== 'function' ) {
		return this;
	}
	if (typeof fulfilled !== 'function' && this.state === 'fulfilled' ||
		typeof rejected !== 'function' && this.state === 'rejected') {
		return this;
	}
	var self = this
	return new Promise( (resolve, reject) => {
		if(fulfilled && typeof fulfilled == "function"){
			var onFulfilled = function (){
				try{
					var result = fulfilled(self.value)
					if(result && typeof result.then === 'function'){
						result.then(resolve, reject)
					}else{
						resolve(result)
					}
				}catch(error){
					reject(error)
				}
			}
			if(self.state === 'pending'){
				self.onFulfilled = onFulfilled
			}else if(self.state === 'fulfilled'){
				onFulfilled()
			}
		}
		if(rejected && typeof rejected == "function"){
			var onRejected = function (){
				try{
					var result = rejected(self.value)
					if(result && typeof result.then === 'function'){
						result.then(resolve, reject)
					}else{
						resolve(result)
					}
				}catch(error){
					reject(error)
				}
			}
			if( self.state === 'pending'){
				self.onRejected = onRejected
			}else if(self.state === 'rejected'){
				onRejected()
			}
		}
	})
}

/*
 *  the methods don't in Promise/A+ 
 */
Promise.prototype.catch = function(onRejected){
	return this.then(null, onRejected)
}

Promise.all = function(iterable){
	if(typeof iterable[Symbol.iterator] !== 'function'){
		throw new TypeError(`${iterable[Symbol.iterator]} is not a function`)
	}
	// Array,TypedArray,String,arguments ==> length; Map,Set ==> size 
	let len = [...iterable].length, i = 0, counter = 0, res = [];
	return new Promise( (resolve, reject) => {
		for(let item of iterable){
			( (i) => {
				Promise.resolve(item).then(function(value){
					counter++
					res[i] = value
					if(counter == len){
						resolve(res)
					}
				},function(reason){
					if(!called){
						reject(reason)
					}
				})
			})(i++)
		}
	})
}

Promise.race = function(iterable){
	if(typeof iterable[Symbol.iterator] !== 'function'){
		throw new TypeError(`${iterable[Symbol.iterator]} is not a function`)
	}
	return new Promise( (resolve,reject) => {
		for(let item of iterable){
			Promise.resolve(item).then(function(value){
				resolve(value)
			},function(reason){
				reject(reason)
			})
		}
	})
}

Promise.resolve = function(value){
	//if(value instanceof this) return value
	//if(value instanceof Promise) return value
	if(value.constructor !== Promise) return value
	return new Promise( (resolve,reject) => {
		if(value && typeof value === 'object' && typeof value.then === 'function'){
			resolve( value.then( v => v))
		}else{
			resolve(value)
		}
	})
}

Promise.reject = function(reason){
	return new Promise( (resolve,reject) => {
		reject(reason)
	})
}
3 回复

写的不错,代码最好 markdown 排版下

@hyj1991 确实,这样看起来舒服些

向大神致敬!

回到顶部