Async-Await:即使一次出现错误,如何在多次等待调用中获取数据?

s.k*_*han 5 javascript asynchronous node.js express async-await

所以我有这个async功能,我可以多次调用 NodeJS 的DNS Api. 前两个调用返回数据,但由于第三个调用,catch 块触发,我没有从前两个调用中获取数据。

由于这完全取决于 query( netflix.com)的类型,因此某些 await 操作可能会因为没有数据而引发错误。但我想要的是我想从其他调用中获取数据,即使其中一些调用存在错误。

这是代码:

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();
Run Code Online (Sandbox Code Playgroud)

上面的代码返回

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'
}
Run Code Online (Sandbox Code Playgroud)

前两个查询的各个输出:

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' }
]
Run Code Online (Sandbox Code Playgroud)

我想如何显示数据:

[
  { 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 }
]
Run Code Online (Sandbox Code Playgroud)

请注意,将有大约 6 个呼叫到DNS API. 由于没有数据,无法确定哪一个会触发错误。这完全取决于查询。

T.J*_*der 5

这是用例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...
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想要成功的结果:

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`...
Run Code Online (Sandbox Code Playgroud)