Skip to content

Promise

[TOC]

索引

构造方法

  • new Promise()(executor)ES2015,用于创建一个 Promise 的实例对象

方法

  • promise.then()(onFulfilled?, onRejected?)ES2015,用于接收当状态变成 fulfilledrejected 时执行的回调函数。
  • promise.catch()(onRejected)ES2015,是 Promise 链式调用中的错误处理方法,用于捕获 Promise 链中发生的任何错误或拒绝。
  • promise.finally()(onFinally)ES2018,用于指定一个无论 Promise 最终状态如何(fulfilled 或 rejected)都会执行的回调函数。

静态方法

  • Promise.resolve()(value)ES2015,用于快速创建一个已解决(fulfilled)的 Promise 对象。提供了一种将值转换为 Promise 的标准方式。
  • Promise.reject()(reason)ES2015,用于立即创建一个已拒绝(rejected)状态的 Promise 对象。它提供了一种快速失败机制,在异步流程中直接抛出错误或拒绝信号。
  • Promise.all()(iterable)ES2015,用于并行处理多个 Promise,当所有 Promise 都成功时返回成功结果,当任意一个 Promise 失败时立即返回失败。
  • Promise.allsettled()(iterable)ES2020,用于等待所有 Promise 完成(无论成功或失败),并返回每个 Promise 的最终状态和结果。不会因某个 Promise 失败而提前终止。
  • Promise.race()(iterable)ES2015,用于获取第一个完成的 Promise 结果(无论成功或失败)。
  • Promise.any()(iterable)ES2021,用于获取第一个成功的 Promise 结果。当所有 Promise 都失败时,它会返回一个包含所有错误信息的 AggregateError。
  • Promise.try()(executor)ES2025,用于统一处理 Promise 链中的同步错误和异步错误
  • Promise.withResolvers()()ES2024

Promise

构造方法

new Promise()@

new Promise()(executor)ES2015,用于创建一个 Promise 的实例对象

  • executor(resolve,reject)=>void,一个同步立即执行的处理业务逻辑的回调函数,有两个自动注入的回调参数:

    • resolvefunction,调用后 Promise 状态变为 fulfilled(成功),并执行 then 方法中的回调。

    • rejectfunction,调用后 Promise 状态变为 rejected(失败),并执行 catch 方法中的回调。

  • 返回:

  • promisePromise,返回一个新创建的 Promise 对象。

基本示例

  1. Promise 完整生命周期

    js
    // 1. 创建 Promise
    const orderPizza = new Promise((resolve, reject) => {
      console.log("厨房开始制作..."); // 同步执行
      
      // 模拟异步操作
      setTimeout(() => {
        const isSuccess = Math.random() > 0.3;
        
        isSuccess 
          ? resolve("🍕 披萨做好了!") 
          : reject("🔥 烤箱坏了!");
      }, 2000);
    });
    
    // 2. 使用 Promise
    orderPizza
      .then(pizza => {
        console.log(`成功:${pizza}`);
        return "开吃!"; // 传递给下一个 then
      })
      .then(message => console.log(message))
      .catch(error => console.error(`失败:${error}`))
      .finally(() => console.log("--- 流程结束 ---"));
    
    /* 可能输出:
       厨房开始制作...
       成功:🍕 披萨做好了!
       开吃!
       --- 流程结束 ---
       
       或:
       厨房开始制作...
       失败:🔥 烤箱坏了!
       --- 流程结束 ---
    */

核心特性

  1. 立即执行executor 在 Promise 创建时立即同步执行

    js
    console.log('开始');
    const p = new Promise(() => {
      console.log('executor 执行');
    });
    console.log('结束');
    
    // 输出顺序:
    // 开始 → executor 执行 → 结束
  2. 错误抛出:在 executor抛出/出现错误等同于调用 reject()

    js
    new Promise(() => {
      throw new Error('出错了!'); // 等同于 reject
      nonExistentFunction(); // 自动触发 reject
    }).catch(err => console.log(err)); // 捕获错误
  3. resolve/reject 特性

    1. 单向不可逆:状态一旦确定不能更改。只有第一次调用生效,后续调用无效。

      js
      new Promise((resolve, reject) => {
        resolve('成功'); // 生效
        reject('失败');  // 被忽略
        resolve('再次尝试'); // 被忽略
      });
    2. 参数传递:参数会传递给后续的 .then().catch()

      js
      new Promise(resolve => resolve({ data: [1, 2, 3] }))
        .then(result => console.log(result.data)); // [1, 2, 3]
    3. resolve 参数类型:不同的参数类型会有不同的处理:

      1. 普通值(包括原始类型、对象、数组等)

        当前 Promise 状态变成 fulfilled。

      2. 另一个 Promise

        当前 Promise 的状态会"跟随"该新 Promise 的状态

      3. thenable 对象(实现了 then() 方法的对象)

        会自动执行该 then 方法,并且根据 then 方法的结果来决定当前 Promise 的状态

  4. 状态查看:可通过 console.dir(promise) 查看 Promise 的当前状态

方法

then()@

promise.then()(onFulfilled?, onRejected?)ES2015,用于接收当状态变成 fulfilledrejected 时执行的回调函数。

  • onFulfilled?res=>void,当 Promise 解决(fulfilled)时调用的函数

  • onRejected?err=>void,当 Promise 拒绝(rejected)时调用的函数

  • 返回:

  • promisePromise,返回一个新的 Promise 对象。其状态取决于回调函数的返回值类型。

核心特性

  1. 异步执行.then() 的回调参数总是异步执行(微任务队列)

    js
    console.log('开始');
    
    Promise.resolve()
      .then(() => console.log('微任务1'))
      .then(() => console.log('微任务2'));
    
    console.log('结束');
    
    /* 输出顺序:
       开始
       结束
       微任务1
       微任务2
    */
  2. 错误处理流程

    错误会沿着 Promise 链传播,直到被捕获:

    js
    Promise.resolve()
      .then(() => {
        throw new Error('错误1');
      })
      .then(() => {
        console.log('不会执行');
      })
      .then(null, err => {
        console.error('捕获:', err.message); // '错误1'
        throw new Error('错误2');
      })
      .catch(err => {
        console.error('最终捕获:', err.message); // '错误2'
      });
  3. 多次调用

    一个 promsie 对象的 then 方法可以被多次调用,每次调用都可以传入对应的 fulfilled 回调,当 Promise 状态变成 fulfilled时这些回调都会被执行。

    js
    const promise = new Promise((resolve, reject) => {
        resolve()
        // reject()
    })
    
    promise.then(res => console.log('第一次调用', res))
    promise.then(res => console.log('第二次调用', res))
    promise.then(res => console.log('第三次调用', res))
  4. 链式调用:then 方法支持链式调用,因为它会返回一个 Promise

    js
    function getUser(id) {
      return fetch(`/users/${id}`)
        .then(response => response.json());
    }
    
    function getOrders(userId) {
      return fetch(`/users/${userId}/orders`)
        .then(response => response.json());
    }
    
    getUser(123)
      .then(user => {
        console.log('用户:', user);
        return getOrders(user.id);
      })
      .then(orders => {
        console.log('订单:', orders);
      })
      .catch(error => {
        console.error('请求失败:', error);
      });

进阶示例

  1. 错误恢复

    js
    fetchPrimaryData()
      .then(processData)
      .catch(primaryError => {
        console.warn('主数据源失败:', primaryError);
        return fetchFallbackData(); // 尝试备用源
      })
      .then(processData)
      .catch(finalError => {
        console.error('所有数据源失败:', finalError);
        return getCachedData(); // 返回缓存
      })
      .then(data => {
        renderUI(data);
      });

catch()@

promise.catch()(onRejected)ES2015,是 Promise 链式调用中的错误处理方法,用于捕获 Promise 链中发生的任何错误或拒绝。

  • onRejectederr=>any,当 Promise 被拒绝(rejected)时调用的函数。可以返回

    • 普通值:会使新 Promise 以该值解决(fulfilled)。

    • Promise:新 Promise 将跟随该 Promise 的状态。

    • 抛出错误:新 Promise 将以该错误拒绝(rejected)。

  • 返回:

  • promisePromise,返回一个新的 Promise 对象,其状态取决于 onRejected 函数的行为:

    • 普通值(包括原始类型、对象、数组等):当前 Promise 状态变成 fulfilled。
    • 另一个 Promise:当前 Promise 的状态会"跟随"该新 Promise 的状态
    • thenable 对象(实现了 then() 方法的对象):会自动执行该 then 方法,并且根据 then 方法的结果来决定当前 Promise 的状态
    • 抛出错误:新 Promise 以该错误拒绝(rejected)

基本示例

  1. 基本使用

    js
    Promise.reject(new Error('操作失败'))
      .catch(error => {
        console.error('捕获错误:', error.message); // "操作失败"
        return '恢复值'; // 返回普通值
      })
      .then(value => {
        console.log('恢复后的值:', value); // "恢复值"
      });

核心特性

  1. 本质:语法糖

    catch 方法本质上是 then 方法的语法糖:

    js
    promise.catch(onRejected);
    
    // 等价于:
    promise.then(undefined, onRejected);
  2. 错误处理机制

    1. 捕获链中任意位置的错误

      js
      Promise.resolve()
        .then(() => {
          throw new Error('错误1');
        })
        .then(() => {
          console.log('不会执行');
        })
        .catch(error => {
          console.error('捕获错误1:', error.message); // "错误1"
          throw new Error('错误2');
        })
        .catch(error => {
          console.error('捕获错误2:', error.message); // "错误2"
        });
    2. 只能捕获前面的错误

      前面抛出的错误会被最近的 catch 捕获

      js
      Promise.resolve()
        .catch(error => console.log('不会执行')) // 没有前面的错误
        .then(() => {
          throw new Error('发生在捕获之后');
        })
        .catch(error => console.log('捕获:', error.message)); // "发生在捕获之后"
    3. 未捕获的拒绝

      如果错误没有被任何 catch 捕获,会导致"未处理的拒绝"(unhandled rejection):

      js
      // 浏览器控制台会显示警告
      new Promise((_, reject) => reject('未处理的错误'));
  3. 与 then 的第二个参数区别

    • catch:能处理整个链的错误
    • then的第二个参数: 只能处理当前 promise 的错误
    js
    // 使用 then 的第二个参数
    promise.then(
      successHandler, 
      errorHandler // 只能处理当前 promise 的错误
    );
    
    // 使用 catch
    promise
      .then(successHandler)
      .catch(errorHandler); // 能处理整个链的错误
  4. 多次调用

    一个 promsie 对象的 catch方法可以被多次调用,每次调用都可以传入对应的 rejected 回调,当 Promise 状态变成 rejected 时这些回调都会被执行。

    js
    const promise = new Promise((resolve, reject) => {
        // resolve()
        reject()
    })
    
    promise.catch(err => console.log('第一次捕获错误:', err))
    promise.catch(err => console.log('第二次捕获错误:', err))
    promise.catch(err => console.log('第三次捕获错误:', err))
  5. 链式调用:catch方法支持链式调用,因为它会返回一个 Promise

进阶示例

  1. 在 async/await 中的等效形式

    js
    // .catch 形式
    function example() {
      return fetchData()
        .then(process)
        .catch(handleError);
    }
    
    // async/await 等效
    async function exampleAsync() {
      try {
        const data = await fetchData();
        return process(data);
      } catch (error) {
        return handleError(error);
      }
    }
  2. 错误类型检查:使用 instanceof 检查错误类型

    js
    fetchData()
      .catch(error => {
        if (error instanceof TypeError) {
          // 处理类型错误
        } else {
          // 其他错误
        }
      });
  3. 重新抛出有意义错误

    js
    validateInput(input)
      .catch(error => {
        // 添加上下文信息
        throw new ValidationError('输入验证失败', { cause: error });
      })
      .catch(error => {
        console.error(error.message); // "输入验证失败"
        console.error('原始错误:', error.cause);
      });

finally()

promise.finally()(onFinally)ES2018,用于指定一个无论 Promise 最终状态如何(fulfilled 或 rejected)都会执行的回调函数。

  • onFinally()=>any,回调不接受参数,当 Promise 敲定(settled)时调用的函数(无论成功或失败)。

  • 返回:

  • promisePromise,返回一个新的 Promise 对象。

基本示例

  1. 基本使用

    js
    Promise.resolve('成功')
      .then(value => console.log('结果:', value))
      .catch(err => console.log('错误:', err))
      .finally(() => console.log('清理操作'))

核心特性

  1. 总是执行:无论 Promise 是成功还是失败,onFinally 都会执行

    js
    // 成功场景
    Promise.resolve('成功')
      .finally(() => console.log('清理操作'))
      .then(value => console.log('结果:', value));
    
    // 失败场景
    Promise.reject('失败')
      .finally(() => console.log('清理操作'))
      .catch(reason => console.log('原因:', reason));
  2. 无参数回调onFinally 回调不接受任何参数,因为它不知道 Promise 的最终状态

    js
    promise
      .then(value => { /* ... */ })
      .catch(error => { /* ... */ })
      .finally(() => {
        // 这里不知道是成功还是失败
        console.log('操作完成');
      });
  3. 状态保持finally() 返回的 Promise 会"镜像"原始 Promise 的状态和值:

    js
    // 保持解决状态
    Promise.resolve(42)
      .finally(() => {})
      .then(value => console.log(value)); // 42
    
    // 保持拒绝状态
    Promise.reject('错误')
      .finally(() => {})
      .catch(reason => console.log(reason)); // "错误"
  4. 值保持

    js
    Promise.resolve('重要值')
      .finally(() => {})
      .then(value => console.log(value)); // "重要值"(值保留)
  5. 错误优先finally() 中的错误会覆盖原始值

    js
    Promise.reject('原始错误')
      .finally(() => {
        throw new Error('新错误');
      })
      .catch(error => console.log(error.message)); // "新错误"(原始错误被覆盖)
  6. 返回值被忽略

    js
    Promise.resolve('原始值')
      .finally(() => '新值') // 被忽略
      .then(value => console.log(value)); // "原始值"

静态方法

resolve()@

Promise.resolve()(value)ES2015,用于快速创建一个已解决(fulfilled)的 Promise 对象。提供了一种将值转换为 Promise 的标准方式。

  • valueany,可以是任何类型的值,它决定了返回的 Promise 状态。

  • 返回:

  • promisePromise,返回一个 Promise 对象。

基本示例

  1. 基本使用

    js
    const p1 = Promise.resolve(42); 
    // 等价于 new Promise(resolve => resolve(42))
    
    p1.then(value => console.log(value)); // 输出: 42

核心特性

  1. 参数类型处理规则

    Promise.resolve() 根据传入值的类型有不同处理方式:

    1. 非 Promise 的普通值

      当前 Promise 状态变成 fulfilled。

    2. thenable 对象

      处理具有 .then() 方法的对象(符合 Promise A+ 规范的 thenable):

    3. Promise 对象

      直接返回传入的 Promise(无额外封装):

    4. 无参数

      创建 undefined 的已解决 Promise:

  2. 执行特性

    1. 同步执行Promise.resolve() 同步返回 Promise,但处理 then 时是异步解决

      js
      // 同步验证
      console.log('开始');
      Promise.resolve().then(() => console.log('微任务'));
      console.log('结束');
      
      // 输出顺序:
      // 开始 → 结束 → 微任务
    2. 错误处理:当 thenable 抛出错误时,返回的 Promise 变为 rejected

      js
      const errorThenable = {
        then: () => { throw new Error('thenable 错误') }
      };
      
      Promise.resolve(errorThenable)
        .catch(err => console.log(err.message)); // 输出: "thenable 错误"

reject()@

Promise.reject()(reason)ES2015,用于立即创建一个已拒绝(rejected)状态的 Promise 对象。它提供了一种快速失败机制,在异步流程中直接抛出错误或拒绝信号。

  • reasonany|Error,拒绝原因,可以是任意类型(通常为 Error 对象或错误描述)

  • 返回:

  • promisePromise,始终返回一个已拒绝状态(rejected)的 Promise 对象

基本示例

  1. 基本使用

    js
    Promise.reject('错误')
      .catch(err => console.log('捕获:', err));

核心特性

  1. 等效写法

    js
    Promise.reject('错误');
    // 等效写法
    new Promise((_, reject) => reject('错误'));
  2. 不可取消性:一旦创建无法取消拒绝状态

    js
    const p = Promise.reject('最终错误');
    // 无法撤回,必须处理
    p.catch(() => {}); // 静默处理避免警告
  3. 参数类型

    reason 可以是任意 JS 值:

    js
    // 1. 错误对象(最佳实践)
    Promise.reject(new Error('文件未找到'));
    
    // 2. 字符串描述
    Promise.reject('无效输入');
    
    // 3. 数字代码
    Promise.reject(404);
    
    // 4. 复杂对象
    Promise.reject({ 
      status: 'error', 
      code: 500 
    });
    
    // 5. 无参数(默认为 undefined)
    Promise.reject(); // 相当于 reject(undefined)
  4. 执行机制

    1. 同步创建Promise.reject() 同步返回 rejected Promise

      js
      console.log('开始');
      const p = Promise.reject('错误');
      console.log('结束');
      
      // 输出顺序:开始 → 结束(同步执行)
    2. 异步处理:拒绝原因通过微任务队列传递

      js
      Promise.reject('错误')
        .catch(err => console.log('捕获:', err));
      
      console.log('先执行我');
      
      // 输出顺序:
      // 先执行我 → 捕获:错误

注意事项

  1. 必须处理拒绝:未处理的拒绝会导致"未捕获的Promise拒绝"警告

    js
    // 浏览器控制台会显示警告
    Promise.reject('未处理错误'); // 报错:Uncaught (in promise) 未处理错误s
  2. 对比 throw

    js
    // 在 async 函数中
    async function fail() {
      throw '错误'; // 等同于返回 Promise.reject('错误')
    }
  3. 错误对象最佳实践:始终使用 Error 对象保留堆栈跟踪

    js
    // 推荐
    Promise.reject(new Error('发生错误'));
    
    // 避免
    Promise.reject('发生错误'); // 无堆栈信息

进阶示例

  1. 统一错误格式

    js
    function toErrorPromise(error) {
      // 包装为统一错误格式
      return Promise.reject({
        timestamp: Date.now(),
        error: error.message || String(error)
      });
    }
    
    fetchData()
      .catch(toErrorPromise)
      .catch(errObj => console.error(errObj));

all()

Promise.all()(iterable)ES2015,用于并行处理多个 Promise,当所有 Promise 都成功时返回成功结果,当任意一个 Promise 失败时立即返回失败。

  • iterableIterator,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。

  • 返回:

  • promisePromise,返回一个新的 Promise 对象。

基本示例

  1. 基本使用

    js
    // 成功情况
    Promise.all([
      Promise.resolve(1),
      Promise.resolve(2),
      Promise.resolve(3)
    ]).then(console.log); // [1, 2, 3]
    
    // 失败情况
    Promise.all([
      Promise.resolve('成功'),
      Promise.reject('失败1'),
      Promise.reject('失败2') // 被忽略
    ]).catch(console.log); // "失败1"

核心特性

  1. 接受任何可迭代对象:Array、Set、Map等

    js
    // 数组(最常用)
    Promise.all([promise1, promise2, promise3]);
    
    // Set
    Promise.all(new Set([p1, p2]));
    
    // Map(处理键值对)
    Promise.all(
      new Map([['key1', p1], ['key2', p2]])
    );
  2. 元素处理规则

    • Promise 对象:等待其解决/拒绝
    • 非 Promise 值:自动用 Promise.resolve() 转换
    • 混合类型:允许混合使用 Promise 和非 Promise 值
    js
    Promise.all([
      fetch('/api/users'),      // Promise
      42,                      // 数字 → Promise.resolve(42)
      { name: '测试' }          // 对象 → Promise.resolve({...})
    ]);
  3. 返回值行为

    成功情况:所有 Promise fulfilled

    • 状态fulfilled

    • 结果值:数组(结果数组顺序始终与输入顺序一致)

      js
      Promise.all([
        Promise.resolve(1),
        Promise.resolve(2),
        Promise.resolve(3)
      ]).then(console.log); // [1, 2, 3]

    失败情况:任意 Promise rejected

    • 状态rejected

    • 拒绝原因:第一个拒绝的 Promise 的原因

      js
      Promise.all([
        Promise.resolve('成功'),
        Promise.reject('失败1'),
        Promise.reject('失败2') // 被忽略
      ]).catch(console.log); // "失败1"
  4. 执行机制

    1. 并行执行:所有 Promise 同时启动,执行顺序不固定;但结果保持声明时的顺序:

      js
      const delay = (ms, val) => new Promise(resolve => 
        setTimeout(() => {
          console.log(`完成: ${val}`);
          resolve(val);
        }, ms)
      );
      
      Promise.all([
        delay(300, '第三'),
        delay(100, '第一'),
        delay(200, '第二')
      ]).then(arr => console.log('结果:', arr));
      
      /* 输出顺序:
         完成: 第一
         完成: 第二
         完成: 第三
         结果: ['第三', '第一', '第二'] ← 保持声明顺序!
      */
    2. 快速失败机制:遇到第一个拒绝立即终止:

      js
      const p1 = new Promise(resolve => setTimeout(resolve, 500, '慢速成功'));
      const p2 = new Promise((_, reject) => setTimeout(reject, 100, '快速失败'));
      
      Promise.all([p1, p2])
        .catch(err => console.log('捕获:', err)); // 100ms后输出"捕获: 快速失败"
      
      // p1 仍在后台运行(但结果被忽略)
    3. 错误传播:只有第一个错误被捕获:

      js
      Promise.all([
        Promise.reject('错误1'),
        Promise.reject('错误2') // 被忽略
      ]).catch(err => console.log(err)); // 只输出"错误1"

allSettled()

Promise.allsettled()(iterable)ES2020,用于等待所有 Promise 完成(无论成功或失败),并返回每个 Promise 的最终状态和结果。不会因某个 Promise 失败而提前终止。

  • iterableIterator,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。

  • 返回:

  • promisePromise,始终返回一个已兑现状态(fulfilled)的 Promise 对象。

基本示例

  1. 基本使用

    js
    const p1 = new Promise(resolve => setTimeout(resolve, 100, '成功'));
    const p2 = new Promise((_, reject) => setTimeout(reject, 200, '失败'));
    
    console.time('耗时');
    Promise.allSettled([p1, p2])
      .then(() => console.timeEnd('耗时')); // 耗时: ~200ms(等待最慢的完成)
    
    /* 输出:
    [
      { status: 'fulfilled', value: '成功' },
      { status: 'rejected', reason: '失败' }
    ]
    */

核心特性

  1. 参数处理

    • 接受任何可迭代对象(数组、Set 等)
    • 元素处理规则
      • Promise 对象:等待其解决
      • 非 Promise 值:自动转换为 Promise.resolve(value)
      • 混合类型:允许混合使用
    js
    // 混合类型示例
    Promise.allSettled([
      fetch('/api/data'),      // Promise
      42,                     // 非 Promise → 自动转换
      Promise.reject('失败')   // 拒绝的 Promise
    ]);
  2. 返回值详解

    返回的 Promise 总是 fulfilled 状态,不会 rejected。结果是一个对象数组,每个对象描述原始 Promise 的结果:

    js
    Promise.allSettled([
      Promise.resolve('成功'),
      Promise.reject('失败'),
      42
    ]).then(results => console.log(results));
    
    /* 输出:
    [
      { status: 'fulfilled', value: '成功' },
      { status: 'rejected', reason: '失败' },
      { status: 'fulfilled', value: 42 }
    ]
    */
  3. 执行机制

    1. 并行执行 + 等待所有完成

      js
      const p1 = new Promise(resolve => setTimeout(resolve, 100, '成功'));
      const p2 = new Promise((_, reject) => setTimeout(reject, 200, '失败'));
      
      console.time('耗时');
      Promise.allSettled([p1, p2])
        .then(() => console.timeEnd('耗时')); // 耗时: ~200ms(等待最慢的完成)
    2. 不中断执行:即使有 Promise 被拒绝,其他 Promise 仍继续执行:

      js
      const tasks = [
        delay(100, '任务1'),
        Promise.reject('任务2失败'),
        delay(300, '任务3')
      ];
      
      Promise.allSettled(tasks).then(results => {
        console.log('任务2状态:', results[1].status); // 'rejected'
        console.log('任务3状态:', results[2].status); // 'fulfilled'(仍执行完成)
      });
    3. 结果顺序:输出数组顺序严格匹配输入顺序

      js
      Promise.allSettled([
        delay(300, 'C'),
        delay(100, 'A'),
        Promise.reject('B')
      ]).then(results => {
        console.log(results[0].value); // 'C'
        console.log(results[1].value); // 'A'
        console.log(results[2].reason); // 'B'
      });
    4. 错误处理:返回的 Promise 本身不会 rejected

      js
      // 无需 .catch(),但需处理内部失败
      Promise.allSettled([Promise.reject('错误')])
        .then(results => {
          // 仍会执行,results[0].status === 'rejected'
        });

进阶示例

  1. 批量操作 + 独立处理结果

    js
    // 批量发送通知,忽略失败项
    function sendNotifications(users) {
      return Promise.allSettled(
        users.map(user => sendEmail(user.email))
      ).then(results => {
        const successes = results
          .filter(r => r.status === 'fulfilled')
          .map(r => r.value);
          
        const failures = results
          .filter(r => r.status === 'rejected')
          .map(r => r.reason);
        
        return { successes, failures }; // 返回值会被 Promise.resolve() 包裹
      });
    }
    
    // 使用
    sendNotifications(userList)
      .then(({successes, failures}) => {
        console.log(`成功: ${successes.length}, 失败: ${failures.length}`);
      });

race()

Promise.race()(iterable)ES2015,用于获取第一个完成的 Promise 结果(无论成功或失败)。

  • iterableIterator,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。

  • 返回:

  • promisePromise,返回一个新的 Promise 对象。

基本示例

  1. 基本使用

    js
    console.time('总耗时');
    Promise.race([
      delay(300, '慢速'),
      delay(100, '中速'),
      delay(50, '快速')
    ]).then(result => {
      console.log('获胜者:', result); // "快速"
      console.timeEnd('总耗时'); // ~50ms
    });

核心特性

  1. 参数处理

    • 接受任何可迭代对象(数组、Set 等)
    • 元素处理规则
      • Promise 对象:等待其解决
      • 非 Promise 值:自动转换为 Promise.resolve(value)
      • 混合类型:允许混合使用
    js
    Promise.race([
      fetch('/api/data'),      // Promise
      42,                     // 非 Promise → 自动转换
      Promise.reject('失败')   // 拒绝的 Promise
    ]);
  2. 返回值行为

    返回的 Promise 状态和结果由第一个完成的 Promise 决定:

    1. 第一个完成的 Promise 成功

      • 状态fulfilled

      • 结果值:第一个成功 Promise 的结果

      js
      const fastResolve = new Promise(res => setTimeout(res, 100, '快速成功'));
      const slowResolve = new Promise(res => setTimeout(res, 200, '慢速成功'));
      
      Promise.race([fastResolve, slowResolve])
        .then(console.log); // 100ms后输出"快速成功"
    2. 第一个完成的 Promise 失败

      • 状态rejected
      • 拒绝原因:第一个失败 Promise 的原因
      js
      const fastReject = new Promise((_, rej) => setTimeout(rej, 100, '快速失败'));
      const slowResolve = new Promise(res => setTimeout(res, 200, '慢速成功'));
      
      Promise.race([fastReject, slowResolve])
        .catch(console.log); // 100ms后输出"快速失败"
  3. 执行机制

    1. 短路机制(Short-circuit):一旦有任一 Promise 完成(无论成功/失败),立即返回结果:

      js
      console.time('总耗时');
      Promise.race([
        delay(300, '慢速'),
        delay(100, '中速'),
        delay(50, '快速')
      ]).then(result => {
        console.log('获胜者:', result); // "快速"
        console.timeEnd('总耗时'); // ~50ms
      });
    2. 忽略后续结果:其他未完成的 Promise 继续执行,但结果被忽略:

      js
      const p1 = new Promise(resolve => 
        setTimeout(() => {
          console.log('p1 完成'); // 仍然会执行
          resolve('p1');
        }, 200)
      );
      
      const p2 = Promise.resolve('p2');
      
      Promise.race([p1, p2])
        .then(winner => console.log('胜者:', winner)); // "p2"
      
      /* 输出:
         胜者: p2
         p1 完成(200ms后)
      */

any()

Promise.any()(iterable)ES2021,用于获取第一个成功的 Promise 结果。当所有 Promise 都失败时,它会返回一个包含所有错误信息的 AggregateError。

  • iterableIterator,可迭代对象(如 Array、Set),包含多个 Promise 或其他值。

  • 返回:

  • promisePromise,返回一个新的 Promise 对象。

基本示例

  1. 基本使用

    js
    // 成功情况:返回第一个成功的 Promise
    Promise.any([
      Promise.reject('错误A'),
      Promise.resolve('第一个成功'),
      Promise.resolve('第二个成功')
    ]).then(console.log); // "第一个成功"
    
    // 失败情况:所有 Promise 都拒绝
    Promise.any([
      Promise.reject('错误1'),
      Promise.reject('错误2')
    ]).catch(error => {
      console.log(error instanceof AggregateError); // true
      console.log(error.errors); // ['错误1', '错误2']
    });

核心特性

  1. 参数处理

    • 接受任何可迭代对象(数组、Set 等)
    • 元素处理规则
      • Promise 对象:等待其解决
      • 非 Promise 值:自动转换为 Promise.resolve(value)
      • 混合类型:允许混合使用
    js
    // 混合类型示例
    Promise.allSettled([
      fetch('/api/data'),      // Promise
      42,                     // 非 Promise → 自动转换
      Promise.reject('失败')   // 拒绝的 Promise
    ]);
  2. 返回值行为

    1. 成功情况:至少一个 Promise fulfilled

      • 状态fulfilled
      • 结果值:第一个成功的 Promise 的结果
      js
      Promise.any([
        Promise.reject('错误A'),
        Promise.resolve('第一个成功'),
        Promise.resolve('第二个成功')
      ]).then(console.log); // "第一个成功"
    2. 失败情况:所有 Promise rejected

      • 状态rejected
      • 拒绝原因AggregateError 对象(包含所有错误信息)
      js
      Promise.any([
        Promise.reject('错误1'),
        Promise.reject('错误2')
      ]).catch(error => {
        console.log(error instanceof AggregateError); // true
        console.log(error.errors); // ['错误1', '错误2']
      });
  3. 执行机制

    1. 短路成功(Short-circuit on fulfillment):当第一个 Promise 成功时立即返回

      js
      const p1 = new Promise(resolve => setTimeout(resolve, 100, '快速成功'));
      const p2 = new Promise(resolve => setTimeout(resolve, 200, '慢速成功'));
      const p3 = Promise.reject('失败');
      
      Promise.any([p3, p1, p2])
        .then(result => console.log(result)); // 100ms后输出"快速成功"
    2. 等待所有失败(Wait for all rejections):当所有 Promise 都失败时,等待所有完成后返回 AggregateError

      js
      const slowReject = new Promise((_, reject) => 
        setTimeout(reject, 200, '慢速失败')
      );
      
      console.time('失败计时');
      Promise.any([
        Promise.reject('快速失败'),
        slowReject
      ]).catch(error => {
        console.log(error.errors); // ['快速失败', '慢速失败']
        console.timeEnd('失败计时'); // ~200ms
      });
  4. 错误处理:必须处理 AggregateError

    js
    Promise.any([...])
      .then(...)
      .catch(error => {
        if (error instanceof AggregateError) {
          console.error('全部失败:', error.errors);
        } else {
          console.error('未知错误:', error);
        }
      });
  5. 忽略后续成功:一旦有 Promise 成功,其他 Promise 的结果将被忽略

    js
    const p = new Promise(resolve => setTimeout(resolve, 1000, '慢速'));
    Promise.any([
      Promise.resolve('快速'),
      p
    ]).then(() => {
      // p 仍在运行(但结果被忽略)
    });

进阶示例

  1. ****:

    js
  2. ****:

    js
  3. ****:

    js

try()

Promise.try()(executor)ES2025,用于统一处理 Promise 链中的同步错误和异步错误

  • executorfunction,要执行的函数,可以返回普通值或 Promise

  • 返回:

  • promisePromise,返回一个 Promise 对象:

    • 如果 executor 返回普通值,Promise 以该值 fulfilled
    • 如果 executor 返回 Promise,则跟随该 Promise 的状态
    • 如果 executor 抛出同步错误,Promise 以该错误 rejected

基本示例

  1. 基本使用

    js
    function fetchData(userId) {
      // 验证输入(可能同步抛出错误)
      if (!userId) throw new Error('用户ID不能为空');
      
      return fetch(`/api/users/${userId}`);
    }
    
    // 安全启动
    Promise.try(() => fetchData(null))
      .then(data => console.log(data))
      .catch(error => console.error('错误:', error.message)); 
      // 输出: "错误: 用户ID不能为空"

核心特性

  1. 概念与背景

    问题:Promise 链中的同步错误

    在原生 Promise 中,同步错误无法被 .catch() 捕获:

    js
    // 同步错误无法被捕获
    function randomFn () {
      if(Math.random() > 0.5) {
        throw new Error('同步错误')
      } else {
        return Promise.reject(new Error('异步错误'))
      }
    }
    
    randomFn().catch(error => {
      console.log('永远不会执行:', error);
    });
    // 未捕获错误:Uncaught Error: 同步错误

    解决方案:Promise.try()

    Promise.try() 提供了一种方式,让同步错误也能被 Promise 的错误处理机制捕获

    js
    Promise.try(() => {
      throw new Error('同步错误');
    }).catch(error => {
      console.log('成功捕获:', error.message); // "同步错误"
    });
  2. 实现原理

    1. 基本实现Promise.try() 的核心实现是一个简单的包装器:

      js
      if (!Promise.try) {
        Promise.try = function(fn) {
          return new Promise((resolve) => {
            resolve(fn());
          });
        };
      }
    2. 完整实现(处理同步错误):更健壮的实现包含错误处理:

      js
      if (!Promise.try) {
        Promise.try = function(fn) {
          return new Promise((resolve, reject) => {
            try {
              // 处理返回值是 Promise 的情况
              const result = fn();
              if (result && typeof result.then === 'function') {
                result.then(resolve, reject);
              } else {
                resolve(result);
              }
            } catch (error) {
              reject(error);
            }
          });
        };
      }
    3. 使用 async/await 的实现:在支持 async/await 的环境中更简洁的实现:

      js
      if (!Promise.try) {
        Promise.try = function(fn) {
          return (async () => fn())();
        };
      }
  3. 与 async/await 的兼容性:在 async 函数中,同步错误会自动被转换为拒绝的 Promise

    js
    // 在 async 函数中,同步错误会自动被转换为拒绝的 Promise
    async function example() {
      throw new Error('自动转换为拒绝');
    }
    
    example().catch(console.error); // 正常工作

withResolvers()【

Promise.withResolvers()()ES2024

  • 返回:

  • result{ promise, resolve, reject }

基本示例

  1. ****:

    js

核心特性

  1. ****:

    js
  2. ****:

    js
  3. ****:

    js

进阶示例

  1. ****:

    js
  2. ****:

    js
  3. ****:

    js