如何使用tokio::join有条件地运行两个函数?

3

我需要同时运行4个函数,但其中一个根据用户输入不同而不同。

如果我使用"if-else",由于Future的原因,会出现"if和else具有不兼容的类型"。

我唯一能想到的方法是创建第三个函数,从其他两个函数中进行选择,但据我所知,它不能同时运行,并且需要等待过程。

另一种方法是制作两个不同的join!,但这似乎很费代码。

在这种情况下我应该怎么做?

tokio::join!(
    self.func1(),
    if self.flag() {
        self.func2()
    } else {
        self.func3()
    },
    self.func4(),
    self.func5()
);

函数签名如下:
pub async fn funcN(&self) -> Result<Vec<String>> {

3个回答

3

最简单的方法可能是使用Box和动态分发。例如,以下代码可以编译:

tokio::join!(
    func1(),
    if flag() {
        Box::pin(func2()) as Pin<Box<dyn Future<Output = _>>>
    } else {
        Box::pin(func3()) as Pin<Box<dyn Future<Output = _>>>
    },
    func4(),
    func5()
);

游乐场


3
您可以在 async 块内使用 if 语句将两种不同的类型合并成一个 future 类型:
tokio::join!(
    func1(),
    async {
        if flag() {
            func2().await
        } else {
            func3().await
        }
    },
    func4(),
    func5()
);

这种方式的调度与其他答案略有不同: flag() 调用被作为未来的一部分而非立即运行。如果不希望这样,可以事先将布尔结果存入变量中。
除此之外,这与Either方法类似,但可以推广到多于两个选择。

2
您可以使用 futures::future::Either 枚举类型:
tokio::join!(
    self.func1(),
    if self.flag() {
        Either::Left(self.func2())
    } else {
        Either::Right(self.func3())
    },
    self.func4(),
    self.func5()
);

Playground


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接