LanguageExt中返回EitherAsync<T1,T2>的方法内如何await代码?
实现方法
EitherAsync没有和TryAsync同名的、直接接收async lambda的静态构造方法,但可以通过两种原生支持的写法实现完全一致的效果,不需要给方法标记async,也不会出现Task漏等的问题。
方式1:通过TryAsync适配(适合异常驱动的错误场景)
TryAsync天生支持async lambda传入,只需要在末尾调用ToEither把捕获到的异常映射为你需要的左值错误类型即可,写法和你之前用TryAsync的习惯完全一致:
using static LanguageExt.Prelude; static EitherAsync<string, int> Divide(int n1, int n2) => TryAsync(async () => { // 内部可以正常await任意异步操作 await Task.Delay(300); return n1 / n2; }) .ToEither(ex => $"计算失败: {ex.Message}");
方式2:直接构造底层委托(适合主动返回业务错误的场景)
EitherAsync的核心是包装了一个Func<Task<Either<L, R>>>的惰性执行委托,你可以直接把async逻辑包在这个委托里传入构造函数,流程中可以随时主动返回左值错误,不需要依赖抛异常:
using static LanguageExt.Prelude; static EitherAsync<string, int> Square(int n) => new(async () => { await Task.Delay(300); if (n < 0) return Left<string, int>("负数不支持该计算逻辑"); return Right<string, int>(n * n); });
之前写法的问题说明
你之前写的Task.Delay(300);没有被正确等待,核心原因是这段代码写在了EitherAsync构造逻辑的外部,属于同步执行的代码,没有被纳入EitherAsync的惰性执行流程。EitherAsync和TryAsync一样是延迟执行的,只有调用Match/Bind/Map等组合或终结方法时才会真正执行内部逻辑,把异步操作写在委托外自然脱离了它的执行调度,不会被正确等待。
两种写法都完全支持内部任意await操作,不会出现async方法标记相关的编译问题。
内容的提问来源于stack exchange,提问作者Avrohom Yisroel
相关产品推荐
相关产品推荐

