实现Promise
参阅这个,层层递进,写得非常好:https://zhuanlan.zhihu.com/p/58428287
极简内核
- Promise可以new, 所以它是一个类 
- new Promise 传入一个函数,所以constructor是fn 
- fn中会有resolve,我们需要自己定义_resolve传进去作为方法,因此有fn(this._resolve.bind(this)) 
- new Promise的实例还可以.then,因此then是Promise的方法 
- 内部维护一个callback,作为传入fn的管理,在调用resolve的时候全部遍历执行 
class Promise {
	callbacks = [];
	constructor(fn) {
		// 内部的_resolve绑定为外部调用
		fn(this._resolve.bind(this))
	}
	then(onFulfilled){
		this.callbacks.push(onFulfilled)
	}
	_resolve(value){
		this.callbacks.forEach(fn => fn(value))
	}
}链式调用
- 由于promise可以组成then的链式调用,then方法必然也返回promise的实例 
- promise.then是微任务,并不是立即执行,需要增加state作为状态进行执行或者收集的判断 
- promise.then可以传递值给下一个then,因此需要内部维护结果,增加value值 
- promise.then 的 onFulfilled 可以为空,直接resolve之前的值,否知先收集,再统一执行 
class Promise {
	callbacks = []
	state = 'pending'
	value = undefined
	constructor(fn) {
		fn(this._resolve.bind(this)
	}
	then(onFulfilled = null){
		// 下面的resolve就是新的实例的this._resolve
		return new Promise(resolve => {
			this._handle({ onFulfilled, resolve })
		})
	}
	_handle(callback){
		if (this.state === 'pending') {
			this.callbacks.push(callback)
			return 
		}
		if (!callback.onFulfilled){
			// 未设置onFulfilled, resolve 结果给下一个then
			callback.resolve(this.value)
			return
		}
		const ret = callback.onFulfilled(this.value)
		callback.resolve(ret)
	}
	_resolve(value) {
		// 先切换状态,这样handle里面的判断不会影响
		this.state = 'fulfilled' 
		this.value = value
		// 一个实例的所有callbacks执行完
		this.callbacks.foreach(callback => this._handle(callback))
	}
}错误处理
- 增加reject 
- onRejected也可以为空 
- 即使是有rejected,那也只是设置状态,之前的callback依然要遍历执行完 
class Promise{
	state = 'pending'
	callbacks = []
	value = undefined
	constructor(fn){
		fn(this._resolve.bind(this), this._reject.bind(this)
	}
	_resolve(value){
		this.state = 'fullfiled'
		this.value = value
		this.callbacks.foreach(callback => this._handle(callback))
	}
	_reject(error){
		this.state = 'rejected'
		this.value = error
		this.callbacks.foreach(callback => this._handle(callback))
	}
	_handle(callback){
		if( this.state === 'pending') {
				this.callbacks.push(callback)
				return
		}
		
		let cb = this.state === 'fullfilled' ? callback.onFulfilled : callback.onRejected
		if (!cb) {
			// 没定义 onFulfilled 或者 onRejected
			cb = this.state === 'fullfilled' ? callback.resolve : callback.reject
			cb(this.value)
			return
		}
		const ret = cb()
		cb(ret)
	}
	then(onFulfilled = null, onRejected = null){
		return new Promise((resolve, reject) => {
				this._handle(onFulfilled, onRejected, resolve, reject)	
			}
	}
}catch
- catch也是接收一个函数 
- catch会挂载一个onError, 然后注册到then作为下一个微任务执行 
- 为什么class是一个callbacks数组。这里就是callback数组会有两个callback了。一个是then注册的,一个是catch注册的。其他的then都是注册一个新的实例 
class Promise{
	state = 'pending'
	callbacks = []
	value = undefined
	constructor(fn){
		fn(this._resolve.bind(this), this._reject.bind(this)
	}
	_resolve(value){
		this.state = 'fullfiled'
		this.value = value
		this.callbacks.foreach(callback => this._handle(callback))
	}
	_reject(error){
		this.state = 'rejected'
		this.value = error
		this.callbacks.foreach(callback => this._handle(callback))
	}
	_handle(callback){
		if( this.state === 'pending') {
				this.callbacks.push(callback)
				return
		}
		
		let cb = this.state === 'fullfilled' ? callback.onFulfilled : callback.onRejected
		if (!cb) {
			// 没定义 onFulfilled 或者 onRejected
			cb = this.state === 'fullfilled' ? callback.resolve : callback.reject
			cb(this.value)
			return
		}
		const ret = cb()
		cb(ret)
	}
	then(onFulfilled = null, onRejected = null){
		// 每次 then 都会创建新的 Promise 实例
		return new Promise((resolve, reject) => {
				this._handle(onFulfilled, onRejected, resolve, reject)	
			}
	}
	catch(onError){
		// onFulfill为null,仅在onReject里面被调用
		return this.then(null, onError)
	}
}实现静态方法
- Promise.resolve对于一个promise实例,会直接返回该实例,因为它自身就有then方法 
- Promise.resolve对于一个对象属性then为函数的,会创建新Promise实例,把这个函数then 传入resolve 
- Promise.resolve对于一个值(即使是函数),会创建新Promise实例,并resolve这个值 
class Promise {
	static resolve(value) {
		if(value && value instanceof Promise){
			return value
		} else if( value && typeof value === 'object' && typeof value.then === 'function') {
			const then = value.then
			return new Promise( resolve => then(resolve))
		} else {
			return new Promise(resolve => resolve(value))
		} 
	}
}实现finally
- finally 不管是onFulfilled 还是 onRejected 都会被调用,因为内部注册到then 上要挂载 两个函数 
class Promise {
	static resolve(value) {
		if(value && value instanceof Promise){
			return value
		} else if( value && typeof value === 'object' && typeof value.then === 'function') {
			const then = value.then
			return new Promise( resolve => then(resolve))
		}  else {
			return new Promise(resolve => resolve())
		}
	}
	static reject(value) {
    if (value && typeof value === 'object' && typeof value.then === 'function') {
      let then = value.then;
      return new Promise((resolve, reject) => {
        then(reject);
      });
    } else {
      return new Promise((resolve, reject) => reject(value));
    }
  }
  finally(onDone) {
    const Promise = this.constructor;
    return this.then(
      value => Promise.resolve(onDone()).then(() => value),
      reason => Promise.resolve(onDone()).then(() => { throw reason })
    );
  }
}最后更新于
这有帮助吗?
