diff --git a/FRENCH/examples-sources/06_02_join/Cargo.toml b/FRENCH/examples-sources/06_02_join/Cargo.toml new file mode 100644 index 00000000..81157f93 --- /dev/null +++ b/FRENCH/examples-sources/06_02_join/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "example_06_02_join" +version = "0.1.0" +authors = ["Taylor Cramer "] +edition = "2018" + +[lib] + +[dev-dependencies] +futures = "0.3" diff --git a/FRENCH/examples-sources/06_02_join/src/lib.rs b/FRENCH/examples-sources/06_02_join/src/lib.rs new file mode 100644 index 00000000..b2cd8719 --- /dev/null +++ b/FRENCH/examples-sources/06_02_join/src/lib.rs @@ -0,0 +1,77 @@ +#![cfg(test)] + +struct Book; +struct Music; +async fn get_book() -> Book { Book } +async fn get_music() -> Music { Music } + +mod naiive { +use super::*; +// ANCHOR: naiive +async fn get_book_and_music() -> (Book, Music) { + let book = get_book().await; + let music = get_music().await; + (book, music) +} +// ANCHOR_END: naiive +} + +mod other_langs { +use super::*; +// ANCHOR: other_langs +// WRONG -- don't do this +async fn get_book_and_music() -> (Book, Music) { + let book_future = get_book(); + let music_future = get_music(); + (book_future.await, music_future.await) +} +// ANCHOR_END: other_langs +} + +mod join { +use super::*; +// ANCHOR: join +use futures::join; + +async fn get_book_and_music() -> (Book, Music) { + let book_fut = get_book(); + let music_fut = get_music(); + join!(book_fut, music_fut) +} +// ANCHOR_END: join +} + +mod try_join { +use super::{Book, Music}; +// ANCHOR: try_join +use futures::try_join; + +async fn get_book() -> Result { /* ... */ Ok(Book) } +async fn get_music() -> Result { /* ... */ Ok(Music) } + +async fn get_book_and_music() -> Result<(Book, Music), String> { + let book_fut = get_book(); + let music_fut = get_music(); + try_join!(book_fut, music_fut) +} +// ANCHOR_END: try_join +} + +mod mismatched_err { +use super::{Book, Music}; +// ANCHOR: try_join_map_err +use futures::{ + future::TryFutureExt, + try_join, +}; + +async fn get_book() -> Result { /* ... */ Ok(Book) } +async fn get_music() -> Result { /* ... */ Ok(Music) } + +async fn get_book_and_music() -> Result<(Book, Music), String> { + let book_fut = get_book().map_err(|()| "Unable to get book".to_string()); + let music_fut = get_music(); + try_join!(book_fut, music_fut) +} +// ANCHOR_END: try_join_map_err +} diff --git a/FRENCH/examples-sources/Cargo.toml b/FRENCH/examples-sources/Cargo.toml index 38cf9482..b64ac40e 100644 --- a/FRENCH/examples-sources/Cargo.toml +++ b/FRENCH/examples-sources/Cargo.toml @@ -1,3 +1,4 @@ [workspace] members = [ + "06_02_join", ] diff --git a/FRENCH/examples/06_02_join/Cargo.toml b/FRENCH/examples/06_02_join/Cargo.toml new file mode 100644 index 00000000..81157f93 --- /dev/null +++ b/FRENCH/examples/06_02_join/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "example_06_02_join" +version = "0.1.0" +authors = ["Taylor Cramer "] +edition = "2018" + +[lib] + +[dev-dependencies] +futures = "0.3" diff --git a/FRENCH/examples/06_02_join/src/lib.rs b/FRENCH/examples/06_02_join/src/lib.rs new file mode 100644 index 00000000..6f4cf024 --- /dev/null +++ b/FRENCH/examples/06_02_join/src/lib.rs @@ -0,0 +1,77 @@ +#![cfg(test)] + +struct Livre; +struct Musique; +async fn obtenir_livre() -> Livre { Livre } +async fn obtenir_musique() -> Musique { Musique } + +mod naiive { +use super::*; +// ANCHOR: naiive +async fn obtenir_livre_et_musique() -> (Livre, Musique) { + let livre = obtenir_livre().await; + let musique = obtenir_musique().await; + (livre, musique) +} +// ANCHOR_END: naiive +} + +mod other_langs { +use super::*; +// ANCHOR: other_langs +// MAUVAISE FAÇON -- ne faites pas cela +async fn obtenir_livre_et_musique() -> (Livre, Musique) { + let future_livre = obtenir_livre(); + let future_musique = obtenir_musique(); + (future_livre.await, future_musique.await) +} +// ANCHOR_END: other_langs +} + +mod join { +use super::*; +// ANCHOR: join +use futures::join; + +async fn obtenir_livre_et_musique() -> (Livre, Musique) { + let future_livre = obtenir_livre(); + let future_musique = obtenir_musique(); + join!(future_livre, future_musique) +} +// ANCHOR_END: join +} + +mod try_join { +use super::{Livre, Musique}; +// ANCHOR: try_join +use futures::try_join; + +async fn obtenir_livre() -> Result { /* ... */ Ok(Livre) } +async fn obtenir_musique() -> Result { /* ... */ Ok(Musique) } + +async fn obtenir_livre_et_musique() -> Result<(Livre, Musique), String> { + let future_livre = obtenir_livre(); + let future_musique = obtenir_musique(); + try_join!(future_livre, future_musique) +} +// ANCHOR_END: try_join +} + +mod mismatched_err { +use super::{Livre, Musique}; +// ANCHOR: try_join_map_err +use futures::{ + future::TryFutureExt, + try_join, +}; + +async fn obtenir_livre() -> Result { /* ... */ Ok(Livre) } +async fn obtenir_musique() -> Result { /* ... */ Ok(Musique) } + +async fn obtenir_livre_et_musique() -> Result<(Livre, Musique), String> { + let future_livre = obtenir_livre().map_err(|()| "Impossible d'obtenir le livre".to_string()); + let future_musique = obtenir_musique(); + try_join!(future_livre, future_musique) +} +// ANCHOR_END: try_join_map_err +} diff --git a/FRENCH/examples/Cargo.toml b/FRENCH/examples/Cargo.toml index 38cf9482..b64ac40e 100644 --- a/FRENCH/examples/Cargo.toml +++ b/FRENCH/examples/Cargo.toml @@ -1,3 +1,4 @@ [workspace] members = [ + "06_02_join", ] diff --git a/FRENCH/src/06_multiple_futures/02_join.md b/FRENCH/src/06_multiple_futures/02_join.md new file mode 100644 index 00000000..872915c5 --- /dev/null +++ b/FRENCH/src/06_multiple_futures/02_join.md @@ -0,0 +1,150 @@ + + +# `join!` + + + +La macro `futures::join` permet d'attendre que plusieurs futures différentes se +terminent pendant qu'elles sont toutes exécutées en concurrence. + + + +## `join!` + + + +Lorsque nous avons besoin de faire plusieurs opérations asynchrones, il peut +être tentant d'utiliser `.await` en série sur elles : + + + +```rust,edition2018,ignore +{{#include ../../examples/06_02_join/src/lib.rs:naiive}} +``` + + + +En revanche, cela peut être plus lent que nécessaire, puisqu'il ne commence +qu'à `obtenir_musique` avant que `obtenir_livre` soit terminé. Dans d'autres +langages, les futures sont exécutées normalement jusqu'à leur fin, donc deux +opérations peuvent être exécutées en concurrence en appelant chacune des +`async fn` pour démarrer les futures, et ensuite attendre la fin des deux : + + + +```rust,edition2018,ignore +{{#include ../../examples/06_02_join/src/lib.rs:other_langs}} +``` + + + +Malheureusement, les futures en Rust ne font rien tant qu'on n'utilise pas +`.await` sur elles. Cela signifie que les deux extraits de code ci-dessus vont +exécuter `future_livre` et `future_musique` en série au lieu de les exécuter en +concurrence. Pour exécuter correctement les deux futures en concurrence, +utilisons `futures::join!` : + + + +```rust,edition2018,ignore +{{#include ../../examples/06_02_join/src/lib.rs:join}} +``` + + + +La valeur retournée par `join!` est une tuple contenant le résultat de chacune +des `Future`s qu'on lui a donné. + + + +## `try_join!` + + + +Pour les futures qui retournent `Result`, il vaut mieux utiliser `try_join!` +plutôt que `join!`. Comme `join!` se termine uniquement lorsque toutes les +sous-futures se soient terminées, il va continuer à calculer les autres futures +même si une de ses sous-futures a retourné une `Err`. + + + +Contrairement à `join!`, `try_join!` va se terminer tout de suite si une des +sous-futures retourne une erreur. + + + +```rust,edition2018,ignore +{{#include ../../examples/06_02_join/src/lib.rs:try_join}} +``` + + + +Notez que les futures envoyées au `try_join!` doivent toutes avoir le même type +d'erreur. Vous pouvez utiliser les fonctions `.map_err(|e| ...)` et +`.err_into()` de `futures::future::TryFutureExt` pour regrouper les types +d'erreurs : + + + +```rust,edition2018,ignore +{{#include ../../examples/06_02_join/src/lib.rs:try_join_map_err}} +``` diff --git a/FRENCH/src/SUMMARY.md b/FRENCH/src/SUMMARY.md index beeca743..a6cd948a 100644 --- a/FRENCH/src/SUMMARY.md +++ b/FRENCH/src/SUMMARY.md @@ -1,3 +1,5 @@ # Table des matières + - [`join!`](06_multiple_futures/02_join.md) + [Traduction des termes](translation-terms.md) diff --git a/FRENCH/src/translation-terms.md b/FRENCH/src/translation-terms.md index 0917f018..6f196784 100644 --- a/FRENCH/src/translation-terms.md +++ b/FRENCH/src/translation-terms.md @@ -5,3 +5,4 @@ français. | Anglais | Français | Remarques | | ------- | ------ | ------ | +| tuple | tuple | - |