Home > front end >  How to conditionally run one of two functions with tokio::join?
How to conditionally run one of two functions with tokio::join?

Time:01-17

I need to run 4 functions concurrently but one of them is different based on user input.

If I use "if-else" I get "if and else have incompatible types" due to Future.

The only way I see is to make a third function that selects from the other two, but it doesn't allow (to my knowledge) to run concurrently due to awaiting.

Another way is to make two different join! but that seems "code expensive".

What should I do in this situation?

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

The function signature is as follows:

pub async fn funcN(&self) -> Result<Vec<String>> {

CodePudding user response:

The easiest way is to use a Box and dynamic dispatch. For example, this compiles:

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()
);

Playground

CodePudding user response:

You can use the futures::future::Either enum:

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

Playground

  •  Tags:  
  • Related