【早阅】深入探索 JavaScript Promises:.all、.allSettled、.race 与 .any

科技   2024-11-16 08:04   福建  

作者:@Angela Caldas
原文:https://dev.to/sucodelarangela/explorando-promises-all-vs-allsettled-race-vs-any-kk9

背景

在 2015 年,随着 ECMAScript 6(ES2015)的发布,JavaScript 引入了 Promise 来简化异步操作的处理。Promise 的出现极大地改善了开发者处理异步任务的体验。随着 JavaScript 版本的不断更新,Promise 也增加了新的方法,如 Promise.allSettled() 和 Promise.any(),这些方法进一步增强了 Promise 的功能。

【第3360期】在JavaScript中从外部解决Promise:实际应用场景

要点

本文主要探讨了 Promise.allPromise.allSettledPromise.race 和 Promise.any 这四个方法的区别及其适用场景。

核心概念回顾

  • Promises:Promises 是处理异步操作的一种模式,代表一个异步操作最终完成或失败的结果。它有三种状态:pending(进行中)、fulfilled(已完成)和 rejected(已拒绝)。

  • 异步操作:指不阻塞主线程,允许程序在等待操作完成的同时继续执行其他任务的操作,例如网络请求、定时器等。

  • 并行执行:指同时执行多个任务,例如同时发起多个网络请求。

  • 错误处理:指捕获和处理异步操作中可能发生的错误。

  • 成功回调:当 Promise 成功完成时执行的函数。

  • 失败回调:当 Promise 失败时执行的函数。

分析

Promise.all vs Promise.allSettled:聚焦结果

Promise.all

  • 接收一个 Promise 数组作为参数。

  • 并行执行所有 Promise。

  • 当所有 Promise 都成功解决时,Promise.all 才会成功解决,并返回所有结果。

  • 如果任何一个 Promise 失败,Promise.all 会立即拒绝,并返回失败的原因,后续的 Promise 将不再执行。

使用 Promise.all 同时获取用户和产品数据。只有当两个 fetch 请求都成功时,才会返回数据。如果任何一个请求失败,Promise.all 就会立即拒绝,并返回失败的原因,后续的 fetch 请求将不再执行。

 async function buscarDadosParalelo () {
const [ usuarios, produtos ] = await Promise.all([
fetch('/api/usuarios').then(resp => resp.json()),
fetch('/api/produtos').then(resp => resp.json()),
]);
return { usuarios, produtos };
}

适用场景:当需要确保所有异步操作都成功完成时,Promise.all 是一个很好的选择。例如,在需要同时获取多个 API 数据并确保所有数据都成功返回时。

Promise.allSettled

  • 同样接收一个 Promise 数组作为参数。

  • 并行执行所有 Promise。

  • 无论 Promise 是成功还是失败,Promise.allSettled 都会返回一个包含每个 Promise 状态的对象数组。

  • 不会因为某个 Promise 失败而中断,所有 Promise 都会执行完毕。

展示了使用 Promise.allSettled 同时获取用户和产品数据。无论请求成功还是失败,Promise.allSettled 都会返回一个包含每个 Promise 状态的对象数组。每个对象包含 status 属性(值为 "fulfilled" 或 "rejected")和 value 或 reason 属性。

 async function buscarDadosParaleloComFalhas () {
const resultados = await Promise.allSettled([
fetch('/api/usuarios').then(resp => resp.json()),
fetch('/api/produtos').then(resp => resp.json()),
]);
// 检查每个结果:
const dados = resultados.map(resultado => {
if (resultado.status === 'fulfilled') {
return resultado.value;
} else {
console.error(resultado.reason);
return null;
}
});
return dados;
}

适用场景:当需要知道所有异步操作的最终状态,而不希望某个操作的失败影响其他操作时,Promise.allSettled 是一个更好的选择。例如,在需要记录多个 API 调用的状态时。

Promise.race vs Promise.any:聚焦速度

Promise.race

  • 接收一个 Promise 数组作为参数。

  • 并行执行所有 Promise。

  • 返回第一个完成的 Promise 的结果,无论是成功还是失败。

使用 Promise.race 获取用户信息。它使用 Promise.race 从缓存、本地数据库和 API 中获取数据,并设置一个 5 秒的超时。 Promise.race 将返回第一个完成的 Promise 的结果,无论是成功还是失败。

 async function buscarDadosUsuario () {
const timeout = new Promise((_, reject) => {
setTimeout(() => reject('Timeout!'), 5000);
});
try {
// 使用 race 获取第一个可用的结果
const resultado = await Promise.race([
buscarCache,
buscarBancoLocal,
buscarAPI,
timeout
]);
return resultado;
} catch (erro) {
console.log(erro);
// 如果出现错误,则在此处停止执行
}
}

适用场景:当需要尽快获取一个结果,而不关心结果是成功还是失败时,Promise.race 是一个合适的选择。例如,在需要设置超时机制时,可以使用 Promise.race 来确保请求在一定时间内完成。

Promise.any

  • 同样接收一个 Promise 数组作为参数。

  • 并行执行所有 Promise。

  • 返回第一个成功解决的 Promise 的结果,忽略所有失败的 Promise。

  • 只有在所有 Promise 都失败时,Promise.any 才会拒绝。

使用 Promise.any 从多个来源获取用户信息。它将尝试从缓存、本地数据库和 API 中获取数据,并返回第一个成功完成的 Promise 的结果。只有当所有 Promise 都失败时,Promise.any 才会拒绝。

 async function buscarDadosUsuario () {
try {
// 返回第一个成功响应的搜索结果
const resultado = await Promise.any([
buscarCache,
buscarBancoLocal,
buscarAPI
]);
return resultado;
} catch (erro) {
console.log(erro);
// 仅当所有搜索都失败时才会执行此操作
}
}

适用场景:当需要确保至少有一个异步操作成功时,Promise.any 是一个理想的选择。例如,在需要从多个数据源获取数据,并选择最快返回成功的数据源时。

选择合适的 Promise 方法取决于应用场景的具体需求。

  • 如果需要所有操作都成功,选择 Promise.all。

  • 如果需要所有结果无论成功或失败,选择 Promise.allSettled。

  • 如果需要最快的结果,选择 Promise.race。

  • 如果只需要至少一个成功结果,选择 Promise.any。

影响

这些新的 Promise 方法为开发者提供了更多的灵活性和控制力,使得处理复杂的异步操作变得更加简单和高效。随着 JavaScript 生态系统的不断发展,这些方法的使用将变得更加普遍,特别是在需要处理大量并发请求的现代 Web 应用中。

结论

Promise.allPromise.allSettledPromise.race 和 Promise.any 各自有其独特的应用场景,开发者应根据具体需求选择合适的方法。随着异步编程在现代应用中的重要性不断提升,掌握这些方法的使用将成为开发者的一项重要技能。未来,随着 JavaScript 标准的进一步演进,我们可能会看到更多增强异步编程体验的新特性。

AI 阅:了解技术资讯的一种方式。

🚀可直接通过阅读原文了解详细内容。


前端早读课
探索前端技术,体验产品的情感, 项目思考的指引,塑造独立开发者的未来。
 最新文章