Async-Await:即使一个错误,如何在多个等待调用中获取数据?
Posted
技术标签:
【中文标题】Async-Await:即使一个错误,如何在多个等待调用中获取数据?【英文标题】:Async-Await: How to get data in multiple await calls even when there is an error in one? 【发布时间】:2021-04-28 15:14:44 【问题描述】:所以我有这个async
函数,我在其中多次调用NodeJS 的DNS Api
。前两个调用返回数据,但由于第三个调用,catch 块触发,我没有从前两个调用中获取数据。
由于这完全取决于查询的类型(netflix.com
),一些等待操作可能会因为没有数据而引发错误。但我想要的是我想从其他调用中获取数据,即使其中一些调用存在错误。
代码如下:
const dnsResolve = async () =>
const query = 'netflix.com';
try
const aRecord = await dns.resolve4(query);
const aaaaRecord = await dns.resolve6(query);
const cnameRecord = await dns.resolveCname(query);
console.log(aRecord);
console.log(aaaaRecord);
console.log(cnameRecord);
catch(err)
console.log(err);
dnsResolve();
以上代码返回
Error: queryCname ENODATA netflix.com
at QueryReqWrap.onresolve [as oncomplete] (internal/dns/promises.js:167:17)
errno: undefined,
code: 'ENODATA',
syscall: 'queryCname',
hostname: 'netflix.com'
前两个查询的单独输出:
aRecord: [
address: '51.73.1.12' ,
address: '55.83.62.128' ,
address: '12.12.82.118'
]
aaaaRecord: [
address: '2406:da200:ff00::222c0:598a' ,
address: '24206:da00:ff00::22c2:44203' ,
address: '2406:da0e0:ff00::36de2:41fd'
]
我想如何显示数据:
[
address: '51.73.1.12' ,
address: '55.83.62.128' ,
address: '12.12.82.118' ,
address: '2406:da200:ff00::222c0:598a' ,
address: '24206:da00:ff00::22c2:44203' ,
address: '2406:da0e0:ff00::36de2:41fd' ,
NO CNAME RECORDS
]
请注意,DNS API
将收到大约 6 个电话。由于没有数据,无法确定哪个会触发错误。这完全取决于查询。
【问题讨论】:
【参考方案1】:这正是Promise.allSettled
的用例:
const results = await Promise.allSettled([
dns.resolve4(query),
dns.resolve6(query),
dns.resolveCname(query),
]);
for (const status, value, reason of results)
if (status === "fulfilled")
// Promise was fulfilled, use `value`...
else
// Promise was rejected, see `reason` for why...
或者如果你只想要成功的结果:
const results = await Promise.allSettled([
dns.resolve4(query),
dns.resolve6(query),
dns.resolveCname(query),
]);
const values = results.filter((status) => status === "fulfilled")
.map((value) => value);
// ...use `values`...
【讨论】:
嘿伙计。所以我应该完全删除 try-catch 块? @A.Amit -allSettled
提供的承诺保证永远不会被拒绝。
抱歉这个菜鸟问题。所以从这个意义上说,我可以删除 try-catch 块?
@A.Amit - 不用担心!您可以删除try
/catch
,如果其中唯一的await
是await
来自allSettled
的承诺,是的,因为它永远不会被拒绝并且allSettled
处理任何拒绝承诺你会进入它。如果你有 other 可能会被拒绝的承诺并且你想处理它们,那么你会保留它,但如果你将所有承诺传递给allSettled
,则不需要它并使用它的结果。以上是关于Async-Await:即使一个错误,如何在多个等待调用中获取数据?的主要内容,如果未能解决你的问题,请参考以下文章
在 Vuejs 中使用 async-await 等待函数内部的赋值
如何使用async-await然后在一个Mocha测试中完成?