Using iter and map instead of a for loop

Hello

I am wondering if this

dish.variations
    .iter()
    .map(|v| add_dish_variation(dish.id, v, &mysql));

is the equivalent of the following?

for dish_variation in dish.variations {
    add_dish_variation(dish.id, &dish_variation, &mysql).await;
}

What code is preferred? And because this code is in the context of Actix-web I am using async functions. The first code (with map) can't use the .await keyword because that gives the following error:

`await` is only allowed inside `async` functions and blocks only allowed inside `async` functions and blocks

Will it still work asynchronous though?

Thanks!

No.

No.

This may be helpful. I found that post with this search.

What about this?

dish.variations
                .iter()
                .map(|v| async { add_dish_variation(dish.id, v, &mysql).await });

async block doesn't do anything unless it's either awaited or spawned, so you'll have to put some of these in the end of iterator chain (with the collect or equivalent).

Could you elaborate? I am looking in streams right now to solve this issue, but your solutions sounds easier.

for dish_variation in dish.variations {
    add_dish_variation(dish.id, &dish_variation, &mysql).await;
}

...is only two lines of code. What could be easier?

1 Like

It indeed seems the for-loop is the easiest solution. I was just wondering for learning-purposes if I could do it in a more functional-Rust-style.

You can .collect::<FuturesUnordered<_>>().await I think?

2 Likes

Since you're asking about for vs .map: You might be confusing map with for_each. The map function does nothing unless the iterator it returns is actually consumed / run to completion. (And this fact should, hopefully, also come up in a warning in case you try writing code like this (unless the code still has errors, in which case those might come first.)

But for_each for iterators doesn't support async, so you would need to work with a Stream then.... or just stick with a for loop.

1 Like

With this, the question of course now is whether OP wants all futures to run concurrently or in sequence. The for loop would run them in sequence, whilst collecting to FuturesUnordered or using Stream API such as for_each_concurrent would execute them concurrently.

3 Likes