如何跳过导致异常的链式承诺?

Posted

技术标签:

【中文标题】如何跳过导致异常的链式承诺?【英文标题】:How can I skip chained promises resulting in exceptions? 【发布时间】:2022-01-12 01:20:54 【问题描述】:

我有多个要访问的 API。

例如

callApis = async function () 

  try 

    var apis = ["apiWithSucess1", "apiWithException", "apiWithSucess1"];

    var response = "";

    for(var i = 0; i < apis.length; i++)

      const apiResponse = await httpRequest.get(apis[i]).promise(); 

      response+=apiResponse.data;
    

    return response;
   
  catch (err) 
    console.log("Exception => ", err);
  
;

callApis().then(function(result)

  console.dir(result);
  
).catch(function(err) 
  
  console.log(err); 
);

现在,当我调用它时,如果数组中有一些引发异常的 api,它会使所有进程崩溃。我希望跳过有异常的 api。

【问题讨论】:

将各个调用封装在try/catch... 您只需要包装将抛出的代码行。您可以在错误处理程序中continue @RandyCasburn 但如果某些 api 在开始或中间抛出异常会恢复吗? 可以this 【参考方案1】:

插入try/catch 子句:

...
let apiResponse
for(var i = 0; i < apis.length; i++)
  try 
    apiResponse = await httpRequest.get(apis[i]).promise(); 
  catch (error) 
     console.error(error)
     continue
  
  response+=apiResponse.data;

...

try 子句中的任何内容都将正常运行,除非抛出异常/错误。在这种情况下,它会出现在catch 子句中,人们可以在其中处理该问题。我只是在其中放置了一个continue 语句,因此您只会得到良好的响应,不过您也可以在响应中添加null,然后添加continue,以便您的响应数组是有序的。

【讨论】:

我建议的一项补充是记录错误。捕获但不记录错误可能会导致在某些内容无法正常工作但没有任何记录时难以调试。【参考方案2】:

您可以使用try/catch 捕获错误,就像在Michal Burgunder's answer 中一样,但如果 API 被链接或以其他方式按顺序调用并不重要,那么您有机会并行调用它们以使过程更快。这将需要调用Promise.allSettled()(或Promise.all(),如果您使用.promise().catch(() =&gt; "") 忽略错误)。

在传统语法中:

callApis = /* no longer async */ function () 
  var apis = ["apiWithSuccess1", "apiWithException", "apiWithSuccess1"];
  // For each API, call promise() and mute errors with catch().
  // Call Promise.all to wait for all results in parallel.
  return Promise.all(apis.map(x => httpRequest.get(x).promise().catch(() => "")))
      // Join the results array as a string with no separators.
      .then(arrayOfStrings => arrayOfStrings.join(""))
      // If any of the above steps fails, log to console and return undefined.
      .catch(err =>  console.log("Exception => ", err); );

在您的async/await 语法中,除了map 中的异常静音catch 调用:

callApis = async function () 
  try 
    var apis = ["apiWithSuccess1", "apiWithException", "apiWithSuccess1"];
    // For each API, call promise() and mute errors with catch().
    // Call Promise.all to wait for all results in parallel.
    var responseArray = await Promise.all(apis.map(
        x => httpRequest.get(x).promise().catch(() => "")));
    // Join the results array as a string with no separators.
    return responseArray.join(""));
   
  catch (err) 
    console.log("Exception => ", err);
  

【讨论】:

以上是关于如何跳过导致异常的链式承诺?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 中的链式承诺

javascript 链式承诺电话

AngularJS - 与其他功能之间的“链式承诺”

如何编写链式异常 Java 类

如何将链式 Promise 与数组的 for 循环一起使用?

线性表---链式存储(双向链表)