JSFiddle - React, Tailwind, and code Playground
JavaScript
/**
* 定义MyPromise的三种状态常量
*/
const PENDING = 'pengding'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
/**
* 判断是某个变量否为function
* @param variable 需要判断的变量
*/
const isFunction = variable => {
return typeof variable === 'function'
}
/**
* 定义then方法回调函数
* @param self promise实例
* @param value 内部的值
* @param status 所要改变的状态
*/
const callback = (self, value, status) => {
/**
* 状态一旦改变,就不会再变
*/
if (self._status !== PENDING) return
self._status = status
/**
* 回调函数
*/
let handle = res => {
self._value = res
/**
* 依次调用then的回调函数
*/
let cb
while (cb = status === FULFILLED ? self._fulfilledQueues.shift() : self._rejectedQueues.shift()) {
cb(res)
}
self._fulfilledQueues = self._rejectedQueues = self._status = self._value = self._resolve = self._reject = undefined
}
if (value instanceof MyPromise) {
/**
* 如果回调函数的参数是一个promise对象,必须等该promise状态改变后在执行当前回调
*/
value.then(handle, handle)
} else {
handle(value)
}
}
/**
* 定义MyPromise类
*/
class MyPromise {
constructor(handle) {
if (!isFunction(handle)) {
throw new Error('MyPromise resolver undefined is not a function')
}
/**
* 存储了then的成功回调函数和失败回调函数的队列, 确保多个then方法的回调函数都能正确执行
*/
this._fulfilledQueues = []
this._rejectedQueues = []
/**
* 初始化promise内部状态和值
*/
this._status = PENDING
this._value = null
/**
* 调用回调函数
*/
try {
handle(this._resolve.bind(this), this._reject.bind(this))
} catch (err) {
this._reject(err)
}
}
/**
* 异步执行回调函数,确保then方法先执行(防止resolve在then执行前先执行)
*/
_resolve(value) {
setTimeout(callback.bind(null, this, value, FULFILLED))
}
_reject(value) {
setTimeout(callback.bind(null, this, value, REJECTED))
...