JS中Promise.all 和 Promise.allsettled区别小结

 更新时间:2026年05月28日 16:13:05   作者:代码猎人  
本文主要介绍了JS中Promise.all 和 Promise.allsettled区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

核心区别对比表

特性Promise.allPromise.allSettled
成功条件所有 Promise 都成功所有 Promise 都完成(无论成功失败)
失败条件任何一个 Promise 失败就立即失败永远不会失败
返回值成功值数组状态对象数组
设计目的需要所有结果都成功才能继续需要知道每个 Promise 的最终状态
ES版本ES6 (2015)ES2020
使用场景并行依赖的操作独立的并行操作

详细对比

1.行为差异

Promise.all - 全有或全无

const p1 = Promise.resolve('成功1');
const p2 = Promise.reject('错误2');  // 这个会失败
const p3 = Promise.resolve('成功3');

Promise.all([p1, p2, p3])
  .then(results => {
    console.log('全部成功:', results);
  })
  .catch(error => {
    console.log('有一个失败:', error); // 输出: "错误2"
    // p1和p3的结果被丢弃!
  });
  • 只要有一个失败,立即失败
  • 其他 Promise 的结果会被丢弃

Promise.allSettled - 全部完成

const p1 = Promise.resolve('成功1');
const p2 = Promise.reject('错误2');
const p3 = Promise.resolve('成功3');

Promise.allSettled([p1, p2, p3])
  .then(results => {
    console.log('全部完成:');
    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        console.log(`p${index + 1}: 成功 - ${result.value}`);
      } else {
        console.log(`p${index + 1}: 失败 - ${result.reason}`);
      }
    });
  });
// 输出:
// 全部完成:
// p1: 成功 - 成功1
// p2: 失败 - 错误2
// p3: 成功 - 成功3
  • 等待所有 Promise 完成
  • 返回每个 Promise 的完整状态信息

2.返回值结构不同

Promise.all 返回值

// 成功时返回: [value1, value2, ...]
Promise.all([Promise.resolve(1), Promise.resolve(2)])
  .then(values => console.log(values)); // [1, 2]

// 失败时返回: 第一个错误
Promise.all([Promise.resolve(1), Promise.reject('错误')])
  .catch(error => console.log(error)); // "错误"

Promise.allSettled 返回值

Promise.allSettled([
  Promise.resolve(1),
  Promise.reject('错误'),
  Promise.resolve(3)
])
.then(results => {
  console.log(results);
  /*
  [
    { status: 'fulfilled', value: 1 },
    { status: 'rejected', reason: '错误' },
    { status: 'fulfilled', value: 3 }
  ]
  */
});

3.实际应用场景

适合 Promise.all 的场景

// 场景1: 需要所有数据才能渲染页面
async function loadDashboard() {
  try {
    const [user, orders, notifications] = await Promise.all([
      fetchUser(),
      fetchOrders(),
      fetchNotifications()
    ]);
    
    // 所有数据都成功才渲染
    renderDashboard({ user, orders, notifications });
  } catch (error) {
    // 任何一个失败就显示错误页面
    showErrorPage('加载数据失败');
  }
}

// 场景2: 并行执行但有依赖关系
async function processOrder(orderId) {
  const [order, inventory, payment] = await Promise.all([
    getOrder(orderId),
    checkInventory(orderId),
    verifyPayment(orderId)
  ]);
  
  // 三个检查都通过才能继续
  return { order, inventory, payment };
}

适合 Promise.allSettled 的场景

// 场景1: 批量操作,需要知道每个结果
async function sendNotifications(users) {
  const results = await Promise.allSettled(
    users.map(user => sendNotification(user))
  );
  
  const successful = results
    .filter(r => r.status === 'fulfilled')
    .map(r => r.value);
    
  const failed = results
    .filter(r => r.status === 'rejected')
    .map(r => r.reason);
    
  console.log(`发送成功: ${successful.length}, 失败: ${failed.length}`);
  return { successful, failed };
}

// 场景2: 多源数据获取,哪个快用哪个
async function getDataFromMultipleSources() {
  const results = await Promise.allSettled([
    fetchFromPrimaryAPI().catch(() => null),    // 主API
    fetchFromBackupAPI1().catch(() => null),    // 备份API1
    fetchFromBackupAPI2().catch(() => null)     // 备份API2
  ]);
  
  // 使用第一个成功的结果
  for (const result of results) {
    if (result.status === 'fulfilled' && result.value) {
      return result.value;
    }
  }
  
  throw new Error('所有数据源都失败了');
}

// 场景3: 清理操作,无论单个成功失败都要继续
async function cleanupResources(resources) {
  const cleanupResults = await Promise.allSettled(
    resources.map(resource => resource.cleanup())
  );
  
  // 记录所有清理结果,但不中断流程
  logCleanupResults(cleanupResults);
}

4.错误处理差异

// 使用 Promise.all 的错误处理
Promise.all([task1(), task2(), task3()])
  .then(([result1, result2, result3]) => {
    // 成功处理
  })
  .catch(error => {
    // 任何一个失败都会到这里
    // 但不知道哪些成功了,哪些失败了
    console.error('某个任务失败:', error);
  });

// 使用 Promise.allSettled 的错误处理
Promise.allSettled([task1(), task2(), task3()])
  .then(results => {
    const errors = results
      .filter(r => r.status === 'rejected')
      .map(r => r.reason);
    
    const successes = results
      .filter(r => r.status === 'fulfilled')
      .map(r => r.value);
    
    if (errors.length > 0) {
      console.log(`${errors.length} 个任务失败,但继续处理成功的`);
      // 可以继续处理 successes
    }
    
    return { successes, errors };
  });

5.互相模拟实现

// 用 Promise.allSettled 模拟 Promise.all
function promiseAll(promises) {
  return Promise.allSettled(promises)
    .then(results => {
      const rejected = results.find(r => r.status === 'rejected');
      if (rejected) {
        throw rejected.reason;  // 抛出第一个错误
      }
      return results.map(r => r.value);  // 返回所有值
    });
}

// 用 Promise.all 模拟 Promise.allSettled(不完美)
function promiseAllSettled(promises) {
  // 为每个 Promise 添加错误处理,确保不会抛出
  const wrappedPromises = promises.map(p =>
    Promise.resolve(p).then(
      value => ({ status: 'fulfilled', value }),
      reason => ({ status: 'rejected', reason })
    )
  );
  return Promise.all(wrappedPromises);
}

总结选择建议

使用Promise.all当:

  • 所有 Promise 必须都成功才能继续
  • 操作有强依赖关系
  • 一个失败意味着整个操作失败
  • 需要快速失败机制

使用Promise.allSettled当:

  • 需要知道每个 Promise 的最终状态
  • 操作是独立的,一个失败不影响其他
  • 需要收集所有结果(成功和失败)
  • 实现降级机制备用方案
  • 执行清理日志记录操作

简单记忆:

  • Promise.all = "全部成功才算成功"
  • Promise.allSettled = "全部完成就是成功"

到此这篇关于JS中Promise.all 和 Promise.allsettled区别小结的文章就介绍到这了,更多相关JS中Promise.all 和 Promise.allsettled内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JavaScript中数组嵌套对象排序方法的示例详解

    JavaScript中数组嵌套对象排序方法的示例详解

    在 JavaScript 中,可以使用 sort() 方法对包含嵌套对象的数组进行排序,本文将通过三个简单的示例为大家进行简单的介绍,需要的可以参考下
    2024-03-03
  • 前端原生js实现拖拽排课效果实例

    前端原生js实现拖拽排课效果实例

    这篇文章主要介绍了如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 浅谈发布订阅模式与观察者模式

    浅谈发布订阅模式与观察者模式

    这篇文章主要介绍了浅谈发布订阅模式与观察者模式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-04-04
  • vscode录音及语音实时转写插件开发并在工作区生成本地mp3文件附踩坑日记!

    vscode录音及语音实时转写插件开发并在工作区生成本地mp3文件附踩坑日记!

    以目前的vscode版本来说,作者并没有开放访问本地媒体权限,所以插件市场里面的所有语音相关插件也并没有直接获取vscode的媒体权限,这篇文章主要介绍了vscode录音及语音实时转写插件开发并在工作区生成本地mp3文件 踩坑日记!,需要的朋友可以参考下
    2023-05-05
  • TypeScript利用TS封装Axios实战

    TypeScript利用TS封装Axios实战

    这篇文章主要介绍了TypeScript利用TS封装Axios实战,TypeScript封装一遍Axios,能进一步巩固TypeScript的基础知识,需要的小伙伴可以参考一下
    2022-06-06
  • 一分钟学会JavaScript中的try-catch

    一分钟学会JavaScript中的try-catch

    这篇文章主要给大家介绍了关于如何通过一分钟学会JavaScript中try-catch的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • JS树形结构根据id获取父级节点元素的示例代码

    JS树形结构根据id获取父级节点元素的示例代码

    这篇文章主要介绍了JS树形结构根据id获取父级节点元素,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-05-05
  • 原生js实现shift/ctrl/alt按键的获取

    原生js实现shift/ctrl/alt按键的获取

    小测试shift、ctrl、alt按键的获取,感兴趣的朋友可以参考下哈,希望可以帮助到你
    2013-04-04
  • JS简单动画封装浅析

    JS简单动画封装浅析

    JS动画,实质是对DOM样式的改变。只要把主流浏览器DOM元素的属性方法搞清楚,做JS动画并不算难
    2011-11-11
  • 如何实现移动端浏览器不显示 pc 端的广告

    如何实现移动端浏览器不显示 pc 端的广告

    随着移动网络的发展,越来越多的人使用手机等移动端浏览网页办公,那么如果在手机打开页面的时候显示大大的联盟广告,用户体验度会非常差,经过一番研究,用下面的方法实现了移动端浏览器不显示PC端广告。
    2015-10-10

最新评论