Announcement

Collapse
No announcement yet.

Rust 1.39 Released With Async-Await Support, Attributes On Function Parameters

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Originally posted by cynical View Post

    First of all, futures and promises are exactly the same thing, in that promise is just another name for a future. Rust futures, however, have an absolutely hideous syntax. I can see why async/await is a godsend here. In JavaScript, promises are actually easier to understand (imo) and nicer than async/await because I actually WANT an obvious syntactic difference between async/sync code. When I see a chain of thens, I know I am dealing with an asynchronous pipeline. I can continue to chain them as long as I want, and the error handling will deal with anything that bubbles up in the process.

    As for an example in JS:
    Code:
    grabUserFromDB(username)
    .then(getFriends)
    .then(getHealthRecords)
    .catch(err => processErr);
    Absolutely trivial, beautiful code. And of course if your functions are rather short you can simply inline them in this fashion:

    Code:
    grabUserFromDB(username)
    .then(user => user.name.toUpperCase())
    .catch(err => processErr);

    The same is also possible of futures in Rust. See the FutureExt then method in the futures crate.

    The problem is that this can often create a deeply nested spaghetti monster if you try to do anything sufficiently complex. In addition to being harder to read and write for a newcomer to async, there are also some patterns which can't be represented safely here, and the generated state machines can get quite complex. Using the async await syntax, this gives the compiler an edge to reduce the generate state machines to much smaller, more efficient structures. It also opens the door to some patterns which previously weren't compatible with the functional approach, without resorting to heap allocations and reference counters. async / await-generated state machines can comfortably work entirely from the stack.

    Code:
    let scope = async {
        grab_user_from_db(&username)
            .await?
            .get_friends()
            .await?
            .get_health_records()
            .await
    };
    
    if let Err(why) = scope.await {
        process_err(why);
    }
    Achieves the same effect in a way that is functional, but without requiring deeply nested functional callbacks, and generates more efficient machine code.

    Comment

    Working...
    X