Promise.all中的错误处理

简介: Promise.all中的错误处理

640.jpg


写在前面


当我们想“并发执行”若干个任务的时候,我们很容易就想到了Promise.all。但是Promise.all有一个缺陷:当有一个任务失败的时候,就会直接进入catch的逻辑了。这个可能并不是我们想要的结果。想象一下我们同时发出了3个网络请求,其中2个正常返回了,有一个reject了,结果却都挂了,只能被迫进入错误处理的逻辑。我们的需求是:出错的那一个请求不会影响到正常的请求。这种情况应该怎么处理呢?


使用await,增加try..catch...逻辑


要解决上面的问题,思路很简单,只需要再外面再包一层Promise就行了,不管内部的Promiseresolved或者rejected了,外层的Promiseresolve就可以了。这样,Promise.all接收到的,永远都是resolvedPromise。两层的Promise看起来有些别扭,为了代码写起来稍微好看一点,我们用awaittry..catch来处理。


/** * @param {Promise} p  */async function promiseWithError(p) {  try {    const res = await p;    return {      err: 0,      data: res    };  } catch(e) {    return {      err: 1    }  }}


下面,通过示例代码来看一下。


const p1 = new Promise((resolve, reject) => {  setTimeout(() => {    resolve('promise resolve 1');  }, 1000);});
const p2 = new Promise((resolve, reject) => {  setTimeout(() => {    resolve('promise resolve 2');  }, 2000);});
const p3 = new Promise((resolve, reject) => {  setTimeout(() => {    reject('promise reject 3');  }, 3000);});
Promise.all([p1, p2, p3])  .then(res => {    console.log('resolve:', res);  })  .catch(err => {    console.log('reject:', err);  });
// 最终输出为:promise reject 3


我们修改一下代码:


Promise.all([p1, p2, p3].map(item => promiseWithError(item)))  .then(res => {    console.log('resolve:', res);  })  .catch(err => {    console.log('reject:', err);  });
// 最终的输出为:// resolve: [{ err: 0, data: "promise resolve 1"}, { err: 0, data:"promise resolve 2"}, { err: 1 }]


我们用promiseWithError把原本的promise包了一层。async可以把任何函数都转换为Promise,最终传入Promise.all的依然是一个Promise数组,没有问题。


这样,我们就解决了问题:Promise.all不会因为其中某一个Promsiereject而导致整个挂掉。


Promise.allSettled


要解决文章开头提到的问题,我们还可以使用Promise.allSettled


Promise.allSettled()方法返回一个在所有给定的promise已被resolve或被reject后的promise,并带有一个对象数组,每个对象表示对应的promise结果。依然使用上面的例子:


Promise.allSettled([p1, p2, p3])    .then(res => {      console.log('resolve:', res);    })    .catch(err => {      console.log('reject:', err);    });
// 最终输出为:// resolve: [{ status: "fulfilled", value: "promise resolve 1" }, { status: "fulfilled", value: "promise resolve 2"}, { status: "rejected", reason: "promise reject 3"} ]


目前,Promise.allSettled处于 tc39 stage-4 阶段,马上就会正式发布了。


写在后面


本文阐述了两种处理Promise.all中错误的方法,对日常开发是很有用处的。关于JavaScript中的异步任务相关总结,可以查看我之前的文章:


【JS基础】从JavaScript中的for...of说起(上):iterator和generator


【JS基础】从JavaScript中的for...of说起(下):async和await



相关文章
|
4月前
|
前端开发
Promise链式调用与错误处理
Promise链式调用是处理异步操作的方式,它按顺序执行多个任务,每个任务返回Promise对象。通过`.then()`指定成功后的操作,`.catch()`处理错误。示例代码展示了如何使用fetch获取数据,根据状态码解析响应并处理数据,错误则通过`.catch()`捕获。另一个例子定义了三个异步函数构成Promise链,依次执行并处理结果,错误同样由`.catch()`统一管理。
|
29天前
|
前端开发 JavaScript
JavaScript异步编程4——Promise错误处理
JavaScript异步编程4——Promise错误处理
33 0
|
4月前
|
前端开发 JavaScript
如何处理 JavaScript 中的异步操作和 Promise?
如何处理 JavaScript 中的异步操作和 Promise?
46 1
|
4月前
|
前端开发 JavaScript
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
在JavaScript中,什么是promise、怎么使用promise、怎么手写promise
69 4
|
4月前
|
前端开发 JavaScript 开发者
JavaScript 中的异步编程:Promise 和 Async/Await
在现代的 JavaScript 开发中,异步编程是至关重要的。本文将介绍 JavaScript 中的异步编程概念,重点讨论 Promise 和 Async/Await 这两种常见的处理异步操作的方法。通过本文的阐述,读者将能够更好地理解和应用这些技术,提高自己在 JavaScript 开发中处理异步任务的能力。
|
3月前
|
前端开发 JavaScript 开发者
JavaScript进阶-Promise与异步编程
【6月更文挑战第20天】JavaScript的Promise简化了异步操作,从ES6开始成为标准。Promise有三种状态:pending、fulfilled和rejected。基本用法涉及构造函数和`.then`处理结果,如: ```javascript new Promise((resolve, reject) => { setTimeout(resolve, 2000, '成功'); }).then(console.log); // 输出: 成功
67 4
|
4月前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
50 0
|
2月前
|
前端开发 JavaScript
JavaScript异步编程:Promise与async/await的深入探索
【7月更文挑战第9天】Promise和async/await是JavaScript中处理异步编程的两大利器。Promise为异步操作提供了统一的接口和链式调用的能力,而async/await则在此基础上进一步简化了异步代码的书写和阅读。掌握它们,将使我们能够更加高效地编写出清晰、健壮的异步JavaScript代码。
|
2月前
|
前端开发 JavaScript 定位技术
JavaScript 等待异步请求数据返回值后,继续执行代码 —— async await Promise的使用方法
JavaScript 等待异步请求数据返回值后,继续执行代码 —— async await Promise的使用方法
34 1
|
3月前
|
前端开发 JavaScript
Promise是JavaScript解决异步问题的构造器,代表未来的不确定值。
【6月更文挑战第27天】Promise是JavaScript解决异步问题的构造器,代表未来的不确定值。它避免了回调地狱,通过链式调用`.then()`和`.catch()`使异步流程清晰。
37 2