#async return value

21 messages · Page 1 of 1 (latest)

paper gazelle
#

all async fn return an impl Future

#

async fn foo() -> Bar { /*code*/ } is just sugar for ```rs
fn foo() -> impl Future<Output = Bar> {
async {
/code/
}
}

#

it already returns an impl Future because it's an async fn

azure ingot
#

No, what you're doing in the definition is correct. Just await the function after calling it

#

There's a warning (it might be from clippy, I can't remember) if you don't await the Future, which should help you get it right here. If you don't await it, then it (generally) won't do anything - so even though you await reqwest in the response function, if you don't also await the Future that response returns, then nothing will really run.

#

You could write response as a non-async function

#

If you don't await it, remove async, and add an impl Future, then it will also work.

#

The reason is because this function is pretty simple. You have a function that runs a request, waits for a response, then returns it. Then, the caller of the function waits for response to finish and gets the value out of it.

#

Exactly

#

Both do the same thing, and they might even get compiled to the same machine code.

#

Well, the error handling is equivalent to just returning the result directly.

paper gazelle
#
fn response(client: Client) -> impl Future<Output = Result<Response, reqwest::Error>> {
  async {
    let response = client.get(URL)
      .send()
      .await?;

      Ok(response)
  }
}
``` this is the desugared version of the function you have
#

it creates a new future that awaits on another future

#

however your current code does not await on the future returned by respponse(), so none of that code in any of these futures actually gets run

azure ingot
#

At a very high level, you can think of Futures as a piece of code that can be asked "are you done yet (and keep doing work if you aren't)?". Your response function can be thought of as piping its "are you done yet" to that of the Future returned by reqwest, basically providing a wrapper around it. We need to periodically check this, both to continue execution when we're done and to ask the Future to keep making progress towards completion.

Even though you call await in that function (calling the "are you done yet" of reqwest's Future), that can only actually get called if the Future returned by response has its "are you done yet" called (which is done by awaiting response()).

paper gazelle
#

the future that response returns has to wait until the future returned by send() is finished

#

Which I then wait on in main.
you should, but aren't

#

you can

paper gazelle
#

you use await anytime a Future needs to get the output of another Future to progress any further

azure ingot
#

One big thing to remember is that Futures generally won't do work if you don't await it. For example, even if you don't care about the response to an HTTP request, you still need to await it for it to go through. If you haven't already, you'll run into tokio tasks, which let you run Futures in the background.