实现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 })
);
}
}
最后更新于
这有帮助吗?