当前位置: 首页 > news >正文

【面试高频】手写 Promise 四大并发方法

Promise 的并发方法: all,allSettled,any,race。这些方法都会接受 promises 数组,返回一个新的 Promise。

Promise.all

成功:所有传入的 promise 状态都为 fulfilled,传回所有的成功的结果数组

失败:只要有一个 promise 状态为 rejected,直接传回失败结果

核心特征(独立、缺一不可):

  • 业务逻辑依赖所有任务的成功结果(缺一不可)

  • 快速失败(任一任务失败则整体终止,无需等待其他任务)

适用场景:

  • 资源预先加载

  • 依赖多接口数据加载

function PromiseAll(promises) {return new Promise((resolve, reject) => {if(!Array.isArray(promises)) {reject(new TypeError('输入参数错误'));}let n = promises.length;let results = new Array(n);let fullfilledCnt = 0;if(n == 0) {return resolve(results);}promises.forEach((promise, i)=> {Promise.resolve(promise).then(result => {results[i] = result;fullfilledCnt ++;if(fullfilledCnt == n) {resolve(results);}}).catch(err => {reject(err);});});});
};// const p1 = Promise.resolve(1);
// const p2 = new Promise(resolve => setTimeout(() => resolve(2), 1000));
// PromiseAll([p1, p2]).then(console.log); // [1, 2](约1m后)// const p3 = Promise.reject('出错了');
// PromiseAll([p1, p3]).catch(console.error); // '出错了'(立即)

Promise.allSettled

成功:所有传入的 promise 状态都为 fulfilled 或 rejected,传回结果为数组,包含状态以及成功或失败的结果

核心特征:完整结果反馈; 不因单个失败而中断

适用场景:

  • 日志上传

  • 非核心资源预加载

function PromiseAllSettled(promises) {return new Promise((resolve, reject) => {if(!Array.isArray(promises)) {reject(new TypeError('输入参数错误'));}let n = promises.length;let results = new Array(n);let cnt = 0;if(n == 0) {return resolve(results);}promises.forEach((promise, i)=> {Promise.resolve(promise).then(value => {results[i] = { stats: 'fullfilled', value };}).catch(error => {results[i] = { stats: 'rejected', error };}).finally(() => {cnt ++;if(cnt == n) {resolve(results);}});});});
};// const promise1 = Promise.resolve(3);
// const promise2 = Promise.reject(new Error('Promise 2 failed'));
// const promise3 = new Promise((resolve) => {
//   setTimeout(resolve, 100, 'foo');
// });// PromiseAll([promise1, promise2, promise3])
//   .then(values => {
//     console.log(values); // 不会执行
//   })
//   .catch(error => {
//     console.error(error); // 输出: Error: Promise 2 failed
//   });

Promise.any

成功:第一个完成的 promise 的状态为 fulfilled,返回成功结果

失败:所有 promise 状态为 rejected,返回失败的数组

特征:结果单一性;全败才败(兜底)

场景:多源数据兜底获取、多节点服务器可用性检测

function PromiseAny(promises) {return new Promise((resolve, reject) => {if(!Array.isArray(promises)) {reject(new TypeError('输入参数错误'));}let n = promises.length;if(n == 0) return;let rejectCnt = 0;let errors = new Array(n);promises.forEach((promise, i)=> {Promise.resolve(promise).then(value => {resolve(value);}).catch(error => {rejectCnt ++;errors[i] = errorif(rejectCnt == n) {reject(new AggregateError(error, "所有promises都被rejected"));}});});});
};// const resolveAfter = (value, delay) => 
//   new Promise(resolve => setTimeout(() => resolve(value), delay));// const rejectAfter = (reason, delay) => 
//   new Promise((_, reject) => setTimeout(() => reject(reason), delay));// // 有一个成功(第一个成功的结果被返回)
// const test1 = async () => {
//   const p1 = rejectAfter('p1失败', 100);
//   const p2 = resolveAfter('p2成功', 200); 
//   const p3 = resolveAfter('p3成功', 150);
//   try {
//     const result = await PromiseAny([p1, p2, p3]);
//     console.log('测试1结果:', result);
//   } catch (err) {
//     console.error('测试1错误:', err);
//   }
// };// test1();

Promise.race

成功:第一个完成的 promise 的状态为 fulfilled,返回成功结果

失败:第一个完成的 promise 的状态为 rejected,返回失败结果

特征:竞速性,最快的响应结果,结果具有单一性

场景:cdn 命中(要的就是最快的响应);用户请求同一接口(避免重复刷新);接口请求超时


function PromiseRace(promises) {return new Promise((resolve, reject) => {if(!Array.isArray(promises)) {reject(new TypeError('输入参数错误'));}let n = promises.length;if(n == 0) return;promises.forEach((promise, i)=> {Promise.resolve(promise).then(value => {resolve(value);}).catch(error => {reject(error);});});});
};// // 测试正常场景
// const p1 = new Promise(resolve => setTimeout(() => resolve(1), 100));
// const p2 = Promise.resolve(2);
// PromiseRace([p1, p2]).then(console.log); // 2(立即,p2先成功)// // 测试失败场景
// const p3 = Promise.reject('出错了');
// const p4 = new Promise(resolve => setTimeout(resolve, 200));
// PromiseRace([p4, p3]).catch(console.error); // '出错了'(立即,p3先失败)
http://www.dtcms.com/a/540786.html

相关文章:

  • 所有网站的名字大全爱客装修官网
  • 互联网大厂Java面试实录:Spring Boot微服务架构实战与JVM深度调优
  • Comparator 比较器 算法排序工具
  • 做网站的流量怎么算钱浦东网站建设箱海运
  • 【LeetCode热题100(55/100)】子集
  • 网站底部设计代码响应式网站检测工具
  • 前端开发,为什么容易被边缘化?
  • PartList::getNamedPart(...)获取对象为空
  • 做食品网站有哪些东西企业信息管理系统erp
  • 廊坊网站制作费用青海西宁网页网站制作
  • 东莞好的网站建设哪家好做设计找素材那个网站最好用
  • php 怎么做视频网站陕西省建设网三类人员成绩公示
  • 多模态的大模型文本分类模型代码(一)——准备阶段
  • 算法———栈
  • 甜点的网站建设规划书企业qq和个人qq有什么区别
  • java公式解析工具
  • 元推理:自指自洽,求道求德,美轮美奂
  • IE-Sec笔记7
  • 【Linux基础知识系列:第一百六十一篇】终端文件管理器:Midnight Commander (mc)
  • Google Veo 3.1 提示词生成器:让 AI 视频创作效率翻倍的免费工具
  • 【医学影像 AI】AutoMorph:基于深度学习的视网膜血管自动化分析工具
  • 郑州做网站找赢博科技定制app开发
  • 使用Docker安装Jenkins:完整指南与最佳实践
  • 手写一个C++字符串类:从底层理解String的实现
  • 大学学院教授委员会制度研究(四)职能设置--杨立恒毕业论文
  • Docker 命令自动补全:临时与持久化配置指南
  • 简单使用Nest+Nacos+Kafka实现微服务
  • 了解学习Redis主从复制
  • 【含文档+PPT+源码】基于java web的篮球馆管理系统系统的设计与实现
  • 眉山建设银行官方网站html5的网站设计与实现是做什么