这是使用异步/等待的正确方法吗?

Posted

技术标签:

【中文标题】这是使用异步/等待的正确方法吗?【英文标题】:Is this the correct way to use async/await? 【发布时间】:2022-01-23 07:24:17 【问题描述】:

我有以下代码:

        var execute = async (assets: DCXComposite[], session: Session) => 
            // this returns a response object with statusCode property. If the status Code is 200, it was a successful operation.
            return await session.performBatchOperation();
        ;

        try 
            var assets: Composite[] = [];
            for (const project of projects) 
                assets.push(project.getComposite());

                if (assets.length === 50) 
                    var result = execute(assets);
                    assets = [];
                
            
         catch (err) 
            Logger.error('Unable to batch delete projects',  error: err );
        

这是如何使用 async/await 吗?如果其中一个执行失败,整个代码是否会失败并被扔到 catch 块中?意味着接下来的 50 个项目没有执行?当 await 抛出错误时会发生什么?

目标是批量删除项目。我正在进行 API 调用并发送要删除的 50 个 API 项目的列表。如果请求成功,则执行调用将返回一个 statusCode = 200 的对象。

【问题讨论】:

async/await 语法使代码的行为更像是同步的。所以是的,如果 execute 调用之一失败,所有后续项目都会被跳过,因为您将进入 catch 块,就像循环中的同步代码一样。 “这是使用 async/await 的正确方法吗?” - 这几乎完全取决于您想要的实际 行为 是什么。 你的意思是我现在在 catch 块中吗?你说“你不在 catch 块”? 你永远不会对result 做任何事情(顺便说一句,这是一个承诺),所以这不是使用async/await 的正确方法。不过,不清楚您的意图是什么,因此我们无法告诉您如何解决。 我在问题中添加了我想要做的事情。希望有帮助 除非您在异步函数中使用try/catch,否则没有理由将return await 用作promise:直接返回promise。 【参考方案1】:

如果您想按顺序处理您的项目,在第一次失败时停止,然后按照 Unmitigated 评论的建议,然后只需 await 调用您的 execute 函数 (await execute(assets);)。

如果您想并行启动所有,并知道其中是否有任何失败,则可以累积返回的Promises并等待组:

const allResults = [];

try 
  for (const project of projects) 
    // ...
    allResults.push(execute(/* ... */));
  
  // Await for ALL promises to complete, or throw at first failure
  await Promise.all(allResults);
 catch (err) 
  // ...

【讨论】:

以上是关于这是使用异步/等待的正确方法吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 List<T> 应用异步和等待?

将 HttpContext.Current.User 与异步等待一起使用的正确方法

我可以等待1等待的2个异步操作吗?

使用异步方法等待 Task.Run 不会在正确的线程上引发异常

如何正确使用等待和通知方法?

使用Task.Wait而不是等待异步编程