实现一个Promise

Promise的大概功能

  • then 接收两个参数,参数1是成功的回调,参数2是失败的回调
  • catch 接收一个参数,失败的回调 
  • finally 接收一个参数,成功/失败都会触发
  • resolve 接收一个参数
  • reject 接收一个参数
  • all 接收一个数组 全部成功或一个失败则结束
  • race 接收一个数组 一个完成则结束
  • any 接收一个有length可遍历的数据,当里面有一个成功则结束,如果一个成功都没有则报错
  • allSettled 接收一个有length可遍历的数据,当里面全部完成则结束,错误不会停止

Promise规范

Promise本质是一个状态机,且状态只能为以下三种:Pending(等待态)Fulfilled(执行态)Rejected(拒绝态),状态的变更是单向的,只能从Pending -> Fulfilled 或 Pending -> Rejected,状态变更不可逆

class IPromise<T> {
  // IPromise的状态,等待中,成功,失败
  status: 'pending' | 'fulfilled' | 'rejected';
  // 存储resolve的队列
  resolveQueue: Array<((value?: T) => any)>;
  // 存储reject的队列
  rejectQueue: Array<((reason: any) => any)>;
  // 给then/catch的数据
  _value: T | undefined;
  // 接收一个函数参数,两个入参是resolve 和 reject
  constructor(executor: (reslove: (value: T) => void, reject: (reason: unknown) => void) => void) {
    this.resolveQueue = [];
    this.rejectQueue = [];
    this.status = 'pending';
    this._value = undefined;
    // 定义一个this,否则resolve/reject不是箭头函数拿不到this
    let _this = this;
    // 定义resolve
    let _resolve = function (_props?: T) {
      // 只有状态是pending才可以进行
      if (_this.status !== 'pending') return;
      // 改变状态
      _this.status = 'fulfilled';
      // 存储数据
      _this._value = _props;
      // 判断是否有成功的回调
      while (_this.resolveQueue?.length) {
        const callback = _this.resolveQueue.shift();
        callback?.(_props);
      }
    };

    // 定义reject
    let _reject = function (_props: any) {
      if (_this.status !== 'pending') return;
      _this.status = 'rejected';
      _this._value = _props;
      while (_this.rejectQueue?.length) {
        const callback = _this.rejectQueue.shift();
        callback?.(_props);
      }
    };
    // 调用入参 传入resolve和reject
    try {
      executor(_resolve, _reject);
    } catch (error) {
      // 如果错误直接执行reject
      _reject(error);
    }
  }

  /**
   * @then 传入两个参数
  */
  then(resolveFn, rejectFn) {
    // 给成功队列添加回调
    this.resolveQueue.push(resolveFn);
    // 给失败队列添加回调
    typeof rejectFn === 'function' && this.rejectQueue.push(rejectFn);
  }
}

到这里就完成了一个最基础的Promise,但是这里我们还不可以链式调用,并且只能处理异步,当Promise是同步时目前是处理不了的,js执行机制从上到下,Promise里面如果是同步,成功和失败的队列则为空,我们的Promise的回调没有再return一个Promise出去所以不能链式,接下来继续完善一下

then的链式调用和处理同步

要想链式调用则需要Promise的then再return一个Promise出去才可以实现,想要处理同步则需要在then里面判断一下当前状态,现在我们继续修改then的代码

/**
 * @then { then传入两个参数,参数1是成功的回调,参数2是失败的 }
*/
then(resolveFn?: (value: T) => any, rejectFn?: (reason: any) => any) {
  // 判断参数是否为函数,如果不是函数会把IPromise的数据返回出去
  typeof resolveFn === 'function' ? null : resolveFn = value => value;
  typeof rejectFn === 'function' ? null : rejectFn = value => value;

  /**
   * @返回一个IPromise链式调用
  */
  return new IPromise((resolve, reject) => {
    /**
     * @给then的参数包装的执行一下判断返回值是否为IPromise
    */
    const fulfilledFn = (value) => {
      const res = resolveFn?.(value);
      res instanceof IPromise ? res?.then(resolve, reject) : resolve(res);
    }

    const rejectedFn = (error) => {
      const res = rejectFn?.(error);
      res instanceof IPromise ? res.then(resolve, reject) : reject(res);
    }

    // 判断IPromise的状态
    switch (this.status) {
      case 'pending':
        // Promise内部是异步,这里为等待中则给队列中添加任务
        this.resolveQueue.push(fulfilledFn);
        this.rejectQueue.push(rejectedFn);
        break;
      case 'fulfilled':
        // 如果Promise内部是同步完成则这里直接调用then里面的成功回调
        fulfilledFn(this._value);
        break;
      case 'rejected':
        // 如果Promise内部是同步完成并且then的失败回调为function则直接调用
        rejectedFn(this._value);
        break;
      default:
        break;
    }

  })
}

现在我们的Promise就可以处理同步与异步,并且可以链式调用了,接下来我们再完成.catch的部分

.catch 失败回调

完成了then方法,其他catch方法就非常简单,因为then的第二个参数也是失败的回调,我们在这里只需调用的return一个then就好了

catch(rejectFn) {
  return this.then(undefined, rejectFn);
}

接下来继续完成.finally的部分

.finally 全部的回调

.finally 不管Promise是成功还是失败都会触发,并且finally拿不到成功/错误的信息,并且finally内部如果return了一个Promise,这个Promise是成功的状态则下一个then拿到的当前Promise的值,如果是失败的状态,则下一个then的失败回调拿到的是finally里面这个Promise的reject值

如下图

 了解了finally的功能我们继续往下写

finally(callback) {
  const fun = (value) => {
    // finally传入的是否为函数
    const res = typeof callback === 'function' && callback?.();
    // 如果finally的回调返回一个IPromise则根据这个IPromise的状态给值,
    if (res instanceof IPromise) {
      return res?.status === 'fulfilled' ? value : res?.value;
    } else {
      // 如果finally回调返回的不是IPromise,则判断当前IPromise的状态为失败则后续的也是失败,否则为成功
      return this.status === 'rejected' ? Promise.reject(value) : value;
    }
  };
  // 调用then传入一个成功一个失败
  return this.then(
    (value) => fun(value),
    // promise<200> 
    (error) => fun(error),
  )
}

finally只要Promise完成就会触发,所以这里咱们需要给then里面添加两个回调

这里我们包装一下finally的回调,因为finally的回调拿不到值所以直接直接调用,如果该回调返回了一个Promise,判断该Promise的状态,如果是成功则把当前Promise的值返回给下一个Promise,否则把回调的Promise值给下一个,当回调非函数或者没有返回Promise时则判断当前promise的状态,如果是失败则返回一个失败,这里用到了Promise.reject,快速返回一个失败的Promise,后续我们会补上该方法

.resolve 快速的返回一个Promise

当.resolve的值为Promise时,该Promise一个为失败则失败

static resolve(value) {
  // 如果参数为Promise则直接返回这个Promise
  if (value instanceof IPromise) return value
  // 如果参数飞Promise则创建一个Promise并且参数当值调用成功
  return new IPromise(_resolve => _resolve(value));
};

.reject 返回一个失败的Promise

static reject(value) {
  // reject不去管参数的是什么类型,直接返回一个失败的Promise
  return new IPromise((resolve, reject) => reject(value));
};

.all 当数组里所有参数都执行完成触发/失败一个也触发

all接收一个数组,当数组里面全部完成则结果then的回调拿到一个数组

当里面有一个失败则走到失败回调

static all(callbackArr: IPromise<any>[]) {
  // 记录有几个完成
  let resultIndex = 0;
  // 记录对应下标的结果
  let result = [] as any[];

  return new IPromise((resolve, reject) => {
    // 如果参数不是数组直接报错
    if (callbackArr instanceof Array) {
      callbackArr?.some((item, index) => {
        // 如果不是Promise则直接添加结果
        if (item instanceof IPromise) {
          item
          .then(res => {
            result[index] = res; // 给对应下标添加结果
            resultIndex++; // 完成数++
            // 判断完成数量是否等于总数
            if (resultIndex === callbackArr?.length) {
              return resolve(result);
            }
          }, err => {
            return reject(err);
          })
        } else {
          result[index] = item;
          resultIndex++;
          if (resultIndex === callbackArr?.length) {
            return resolve(result);
          }
        }
      })
    } else {
      reject(`TypeError: ${typeof callbackArr} ${callbackArr} is not iterable (cannot read property Symbol(Symbol.iterator))`)
    }
  })

}

.race 竞速,有一个完成则结束

race接收一个数组,当数组里面有一个完成则结束,返回完成的结果

static race(callbackArr: IPromise<any>[]) {
  return new IPromise((resolve, reject) => {
    // 如果参数不是数组直接报错
    if (callbackArr instanceof Array) {
      callbackArr?.some((item, index) => {
        // 如果不是Promise则直接添加结果
        if (item instanceof IPromise) {
          item
          .then(res => {
            return resolve(res);
          }, err => {
            return reject(err);
          })
        } else {
          return resolve(item);
        }
      })
    } else {
      reject(`TypeError: ${typeof callbackArr} ${callbackArr} is not iterable (cannot read property Symbol(Symbol.iterator))`)
    }
  })
}

代码上只需要把all的那些结果总数,结果数组去掉,一个完成直接结束调该Promise

2023 - 03 - 09 补充 start

.any 任意一个成功则结束,race是任意一个完成则结束

 入参是一个有length可遍历的类型,所以这里使用for循环,如果循环项非Promise/Promise.then则直接resolve,如果没有一个resolve则会自动到reject

用then接收,如果是成功则return 该值,否则return一个Promise的错误

/**
 * @any 任意一个成功则返回
*/
static any(promiseArr) {
  if (typeof promiseArr.length === 'number') {
    return new IPromise((resolve, reject) => {
      for (let i = 0; i < promiseArr.length; i++) {
        if (promiseArr[i] instanceof IPromise) {
          promiseArr[i]
            .then(res => {
              return resolve(res);
            })
        } else {
          // 如果当前值不是Promise则直接成功
          return resolve(promiseArr[i]);
        }

      }
    })
      // 拿到当前Promise的回调,如果走then则代表完成直接把值抛出去
      .then(res => {
        return res;
      }, () => {
        // 如果catch则代表所有的promise都是rejected
        return Promise.reject('AggregateError: All promises were rejected');
      })
  } else {
    return IPromise.reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator)) at IPromise.allSettled`)
  }
}

 

.allSettled 所有的完成则结束,all是所有的成功/有一个失败则结束

入参是一个有length可遍历的类型,所以这里使用for循环,如果循环项非Promise/Promise.then则给result添加对应下标添加数据,rindex++,判断是否为最后一个

/**
 * @allSettled 当数组里的promise全部执行完成返回结果,中途报错不会影响结果
*/
static allSettled(promiseArr: IPromise<any>[]) {
  // 有几个已执行
  let rindex = 0;
  // promise对应的结果
  let result = [] as any[];

  // return一个Promise
  return new IPromise((resolve, reject) => {
    // 封装一个方法,参数1是结果,参数2是当前下标,参数3可选的一个状态,默认为fulfilled成功
    function pushRes(value, index, type?: 'rejected') {
      result[index] = {
        type: type || 'fulfilled',
        value: value
      };
      rindex++;
      // 判断当前是否全部执行完成
      if (rindex === promiseArr?.length) {
        resolve(result);
      }
    };
    if (typeof promiseArr.length === 'number') {
      for (let i = 0; i < promiseArr.length; i++) {
        if (promiseArr[i] instanceof IPromise) {
          promiseArr[i]
            .then(res => {
              pushRes(res, i);
            }, err => {
              pushRes(err, i, 'rejected');
            })
        } else {
          pushRes(promiseArr[i], i);
        }
      }
    } else {
      reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator)) at IPromise.allSettled`)
    }
  })
}

2023 - 03 - 09 补充 end

到这里我们的Promise就完成了,下面我上一下全量代码

class IPromise<T> {
  // IPromise的状态,等待中,成功,失败
  status: 'pending' | 'fulfilled' | 'rejected';
  // 存储resolve的函数
  resolveQueue: Array<((value?: T) => any)>;
  // 存储reject的函数
  rejectQueue: Array<((reason: any) => any)>;
  // 给then/catch的数据
  _value: T | undefined;
  // 接收一个函数参数,两个入参是resolve 和 reject
  constructor(executor: (reslove: (value: T) => void, reject: (reason: unknown) => void) => void) {
    this.resolveQueue = [];
    this.rejectQueue = [];
    this.status = 'pending';
    this._value = undefined;
    // 定义一个this,否则resolve等不是箭头函数拿不到this
    let _this = this;
    // 定义resolve
    let _resolve = function (_props?: T) {
      if (_this.status !== 'pending') return;
      _this.status = 'fulfilled';
      _this._value = _props;
      while (_this.resolveQueue?.length) {
        const callback = _this.resolveQueue.shift();
        callback?.(_props);
      }
    };

    // 定义reject
    let _reject = function (_props: any) {
      if (_this.status !== 'pending') return;
      _this.status = 'rejected';
      _this._value = _props;
      while (_this.rejectQueue?.length) {
        const callback = _this.rejectQueue.shift();
        callback?.(_props);
      }
    };
    // 调用入参
    try {
      executor(_resolve, _reject);
    } catch (error) {
      // 如果错误直接执行reject
      _reject(error);
    }
  }

  /**
   * @then { then传入两个参数,参数1是成功的回调,参数2是失败的 }
  */
  then(resolveFn?: (value: T) => any, rejectFn?: (reason: any) => any) {
    // 判断参数是否为函数,如果不是函数会把IPromise的数据返回出去
    typeof resolveFn === 'function' ? null : resolveFn = value => value;
    typeof rejectFn === 'function' ? null : rejectFn = value => value;

    /**
     * @返回一个IPromise链式调用
    */
    return new IPromise((resolve, reject) => {
      /**
       * @给then的参数包装的执行一下判断返回值是否为IPromise
      */
      const fulfilledFn = (value) => {
        const res = resolveFn?.(value);
        res instanceof IPromise ? res?.then(resolve, reject) : resolve(res);
      }

      const rejectedFn = (error) => {
        const res = rejectFn?.(error);
        res instanceof IPromise ? res.then(resolve, reject) : reject(res);
      }

      // 判断IPromise的状态
      switch (this.status) {
        case 'pending':
          // Promise内部是异步,这里为等待中则给队列中添加任务
          this.resolveQueue.push(fulfilledFn);
          this.rejectQueue.push(rejectedFn);
          break;
        case 'fulfilled':
          // 如果Promise内部是同步完成则这里直接调用then里面的成功回调
          fulfilledFn(this._value);
          break;
        case 'rejected':
          // 如果Promise内部是同步完成并且then的失败回调为function则直接调用
          rejectedFn(this._value);
          break;
        default:
          break;
      }

    })
  }

  /**
   * @catch { 错误的回调 }
  */
  catch(rejectFn) {
    /**
     * @直接调用then传入一个undefined和一个catch的回调
    */
    return this.then(undefined, rejectFn);
  }

  /**
   * @finally { 回调不管成功还是错误 }
  */
  finally(callback?: any) {
    const fun = (value) => {
      const res = typeof callback === 'function' && callback?.();
      // 如果finally的回调返回一个IPromise则根据这个IPromise的状态给值,
      if (res instanceof IPromise) {
        return res?.status === 'fulfilled' ? value : res?._value;
      } else {
        // 如果finally回调返回的不是IPromise,则判断当前IPromise的状态为失败则后续的也是失败,否则为成功
        return this.status === 'rejected' ? IPromise.reject(value) : value;
      }
    };
    // 调用then传入一个成功一个失败
    return this.then(
      (value) => fun(value),
      // promise<200> 
      (error) => fun(error),
    )
  }

  /**
   * @resolve 返回一个IPromise实例
   * */
  static resolve<R>(value?: R | IPromise<R>): IPromise<R> {
    // resolve传入一个参数,返回一个promise,如果该参数为promise则直接返回
    if (value instanceof IPromise) return value;
    return new IPromise((resolve) => resolve(value as R));
  };

  /**
   * @reject 返回一个失败的IPromise实例
   * */
  // IPromise.reject();
  static reject<R>(value: R): IPromise<R> {
    // reject传入一个参数,返回promise,不管参数的类型
    return new IPromise((resolve, reject) => reject(value));
  };

  /**
   * @all 当数组里的promise全部执行完成或者有一个报错则结束
  */
  static all(promiseArr: IPromise<any>[]) {
    // 有几个已执行
    let rindex = 0;
    // promise对应的结果
    let result = [] as any[];

    // return一个Promise
    return new IPromise((resolve, reject) => {
      // 如果入参不是数组则直接reject报错
      if (promiseArr instanceof Array) {
        promiseArr?.forEach((item, index) => {
          // 如果不是Promise则直接给对应位置添加返回值
          if (item instanceof IPromise) {
            item
              .then(res => {
                result[index] = res;
                rindex++;
                // 判断当前是否全部执行完成
                if (rindex === promiseArr?.length) {
                  resolve(result);
                }
              }, err => {
                reject(err);
              })
          } else {
            result[index] = item;
            rindex++;
            if (rindex === promiseArr?.length) {
              resolve(result);
            }
          }
        })
      } else {
        reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator))`)
      }
    })
  }

  /**
   * @race 当数组里的promise有一个完成则结束
  */
  static race(promiseArr: IPromise<any>[]) {
    return new IPromise((resolve, reject) => {
      // 如果入参不是数组则直接reject报错
      if (promiseArr instanceof Array) {
        promiseArr?.some((item, index) => {
          // 如果不是Promise则直接给对应位置添加返回值
          if (item instanceof IPromise) {
            item
              .then(res => {
                return resolve(res);
              }, err => {
                return reject(err);
              })
          } else {
            return resolve(item);
          }
        })
      } else {
        reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator))`)
      }
    })
  }

  /**
   * @any 任意一个成功则返回
  */
  static any(promiseArr) {
    if (typeof promiseArr.length === 'number') {
      return new IPromise((resolve, reject) => {
        for (let i = 0; i < promiseArr.length; i++) {
          if (promiseArr[i] instanceof IPromise) {
            promiseArr[i]
              .then(res => {
                return resolve(res);
              })
          } else {
            // 如果当前值不是Promise则直接成功
            return resolve(promiseArr[i]);
          }

        }
      })
        // 拿到当前Promise的回调,如果走then则代表完成直接把值抛出去
        .then(res => {
          return res;
        }, () => {
          // 如果catch则代表所有的promise都是rejected
          return Promise.reject('AggregateError: All promises were rejected');
        })
    } else {
      return IPromise.reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator)) at IPromise.allSettled`)
    }
  }

  /**
   * @allSettled 当数组里的promise全部执行完成返回结果,中途报错不会影响结果
  */
  static allSettled(promiseArr: IPromise<any>[]) {
    // 有几个已执行
    let rindex = 0;
    // promise对应的结果
    let result = [] as any[];

    // return一个Promise
    return new IPromise((resolve, reject) => {
      // 封装一个方法,参数1是结果,参数2是当前下标,参数3可选的一个状态,默认为fulfilled成功
      function pushRes(value, index, type?: 'rejected') {
        result[index] = {
          type: type || 'fulfilled',
          value: value
        };
        rindex++;
        // 判断当前是否全部执行完成
        if (rindex === promiseArr?.length) {
          resolve(result);
        }
      };
      if (typeof promiseArr.length === 'number') {
        for (let i = 0; i < promiseArr.length; i++) {
          if (promiseArr[i] instanceof IPromise) {
            promiseArr[i]
              .then(res => {
                pushRes(res, i);
              }, err => {
                pushRes(err, i, 'rejected');
              })
          } else {
            pushRes(promiseArr[i], i);
          }
        }
      } else {
        reject(`TypeError: ${typeof promiseArr} ${promiseArr} is not iterable (cannot read property Symbol(Symbol.iterator)) at IPromise.allSettled`)
      }
    })
  }
}

<think>我们来实现一个简单的Promise,遵循Promise/A+规范的核心部分。由于完整实现较为复杂,这里我们实现一个简化版,包含基本功能:状态管理、then方法、异步执行支持。 核心要点: 1. Promise有三种状态:pending, fulfilled, rejected 2. 初始化时传入一个执行器函数(executor),该函数立即执行,接收两个参数:resolve和reject 3. then方法用于注册回调,当状态改变时调用对应的回调 4. 支持异步:当状态还未改变时,将回调暂存,待状态改变后执行 我们将按照以下步骤实现: 1. 定义状态常量 2. 构造函数:初始化状态、值、原因以及回调队列 3. 实现resolve和reject内部函数 4. 实现then方法 5. 处理executor中的异常 注意:此实现不包含链式调用(即then返回新的Promise)和值穿透等高级特性,仅提供基本功能。 代码实现:</think>### 简单实现一个 Promise #### 基础版 Promise 实现(符合 Promise/A+ 规范核心部分) ```javascript class MyPromise { constructor(executor) { this.state = 'pending'; // 状态: pending, fulfilled, rejected this.value = null; // 成功时的值 this.reason = null; // 失败时的原因 this.onFulfilledCallbacks = []; // 成功回调队列 this.onRejectedCallbacks = []; // 失败回调队列 const resolve = (value) => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; // 执行所有成功回调 this.onFulfilledCallbacks.forEach(fn => fn()); } }; const reject = (reason) => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; // 执行所有失败回调 this.onRejectedCallbacks.forEach(fn => fn()); } }; try { // 立即执行执行器函数 executor(resolve, reject); } catch (error) { // 捕获执行器中的异常 reject(error); } } then(onFulfilled, onRejected) { // 处理值穿透 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; }; // 返回新Promise实现链式调用 return new MyPromise((resolve, reject) => { const handleFulfilled = () => { try { const result = onFulfilled(this.value); resolve(result); } catch (error) { reject(error); } }; const handleRejected = () => { try { const result = onRejected(this.reason); resolve(result); } catch (error) { reject(error); } }; if (this.state === 'fulfilled') { // 异步执行 setTimeout(handleFulfilled, 0); } else if (this.state === 'rejected') { setTimeout(handleRejected, 0); } else { // pending状态 this.onFulfilledCallbacks.push(() => setTimeout(handleFulfilled, 0)); this.onRejectedCallbacks.push(() => setTimeout(handleRejected, 0)); } }); } // 简单实现catch方法 catch(onRejected) { return this.then(null, onRejected); } // 简单实现finally方法 finally(callback) { return this.then( value => MyPromise.resolve(callback()).then(() => value), reason => MyPromise.resolve(callback()).then(() => { throw reason; }) ); } // 静态resolve方法 static resolve(value) { if (value instanceof MyPromise) return value; return new MyPromise(resolve => resolve(value)); } // 静态reject方法 static reject(reason) { return new MyPromise((_, reject) => reject(reason)); } } ``` #### 使用示例 ```javascript // 基本使用 const p1 = new MyPromise((resolve, reject) => { setTimeout(() => resolve('成功!'), 1000); }); p1.then(result => { console.log(result); // 1秒后输出"成功!" return '链式调用'; }).then(msg => { console.log(msg); // 输出"链式调用" }); // 错误处理 const p2 = new MyPromise((resolve, reject) => { reject(new Error('出错了!')); }); p2.catch(error => { console.error(error.message); // 输出"出错了!" }); // 静态方法 MyPromise.resolve('立即解析') .then(console.log); // 输出"立即解析" MyPromise.reject('立即拒绝') .catch(console.error); // 输出"立即拒绝" ``` #### 实现要点解析 1. **状态机设计** - 三种状态:`pending`、`fulfilled`、`rejected` - 状态单向转换:`pending` → `fulfilled` 或 `pending` → `rejected` 2. **异步处理** - 使用 `setTimeout` 确保回调异步执行 - 回调队列处理异步操作完成前的多次 `then` 调用 3. **链式调用** - `then` 方法返回新 Promise 对象 - 值穿透处理:`then(null, ...)` 和 `catch` 实现 4. **错误处理** - 执行器函数错误捕获 - 回调函数错误传播 #### 与原生 Promise 的差异 | 特性 | 原生 Promise | 本实现 | |--------------------|----------------------|---------------------| | 微任务队列 | 使用微任务 | 使用宏任务(setTimeout) | | Promise.all | 支持 | 未实现 | | Promise.race | 支持 | 未实现 | | 性能优化 | 高度优化 | 基础实现 | | 规范符合度 | 完整 Promise/A+ | 核心部分 | #### 进阶扩展建议 1. **实现 Promise.all** ```javascript static all(promises) { return new MyPromise((resolve, reject) => { const results = []; let completed = 0; promises.forEach((promise, index) => { MyPromise.resolve(promise).then( value => { results[index] = value; if (++completed === promises.length) resolve(results); }, reject // 任一失败立即reject ); }); }); } ``` 2. **实现 Promise.race** ```javascript static race(promises) { return new MyPromise((resolve, reject) => { promises.forEach(promise => { MyPromise.resolve(promise).then(resolve, reject); }); }); } ``` 3. **添加取消功能** ```javascript constructor(executor) { // ...其他代码... this.isCancelled = false; const cancel = () => { this.isCancelled = true; reject(new Error('Promise cancelled')); }; executor(resolve, reject, cancel); // 添加取消函数 } // 使用 const p = new MyPromise((resolve, reject, cancel) => { // 设置取消函数 window.cancelRequest = cancel; }); ``` #### 应用场景 1. **API请求封装** ```javascript function fetchData(url) { return new MyPromise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onload = () => resolve(JSON.parse(xhr.responseText)); xhr.onerror = () => reject(new Error('Request failed')); xhr.send(); }); } ``` 2. **异步流程控制** ```javascript MyPromise.resolve() .then(() => loadUserData()) .then(user => loadOrders(user.id)) .then(orders => processOrders(orders)) .catch(handleError); ``` 3. **超时控制** ```javascript function withTimeout(promise, timeout) { return MyPromise.race([ promise, new MyPromise((_, reject) => setTimeout(() => reject(new Error('Timeout')), timeout) ) ]); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值