diff --git a/blog/content/edition-2/posts/12-async-await/index.ru.md b/blog/content/edition-2/posts/12-async-await/index.ru.md index 90f01ad5..051c9be3 100644 --- a/blog/content/edition-2/posts/12-async-await/index.ru.md +++ b/blog/content/edition-2/posts/12-async-await/index.ru.md @@ -159,7 +159,7 @@ pub enum Poll { Теперь мы знаем, как определяются футуры, и понимаем основную идею метода `poll`. Однако мы все еще не знаем, как эффективно работать с футурами. Проблема в том, что они представляют собой результаты асинхронных задач, которые могут быть еще недоступны. На практике, однако, нам часто нужны эти значения непосредственно для дальнейших вычислений. Поэтому возникает вопрос: как мы можем эффективно получить значение, когда оно нам нужно? -#### Ожидание Futures +#### Ожидание Futures {#waiting-on-futures} Один из возможных ответов — дождаться, пока футура исполнится. Это может выглядеть примерно так: @@ -235,7 +235,7 @@ fn file_len() -> impl Future { [_Futures с нулевой стоимостью в Rust_]: https://aturon.github.io/blog/2016/08/11/futures/ -##### Недостатки +##### Недостатки {#drawbacks} Хотя комбинаторы футур позволяют писать очень эффективный код, их может быть сложно использовать в некоторых ситуациях из-за системы типов и интерфейса на основе замыканий. Например, рассмотрим такой код: @@ -305,7 +305,7 @@ async fn example(min_len: usize) -> String { ([Попробовать](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=d93c28509a1c67661f31ff820281d434)) -Эта функция - прямой перевод `example` написанной [выше](#Недостатки), которая использовала комбинаторы. Используя оператор `.await`, мы можем получить значение футуры без необходимости использования каких-либо замыканий или типов `Either`. В результате мы можем писать наш код так же, как если бы это был обычный синхронный код, с той лишь разницей, что _это все еще асинхронный код_. +Эта функция - прямой перевод `example` написанной [выше](#drawbacks), которая использовала комбинаторы. Используя оператор `.await`, мы можем получить значение футуры без необходимости использования каких-либо замыканий или типов `Either`. В результате мы можем писать наш код так же, как если бы это был обычный синхронный код, с той лишь разницей, что _это все еще асинхронный код_. #### Преобразования Конечных Автоматов @@ -504,7 +504,7 @@ fn example(min_len: usize) -> ExampleStateMachine { Заметьте, что эта функция не запускает автомат. Это фундаментальное архитектурное решение для футур в Rust: они ничего не делают, пока не будет произведена первая проверка на готовность. -#### Закрепление +#### Закрепление {#pinning} Мы уже несколько раз столкнулись с понятием _закрепления_ (pinnig, пиннинг) в этом посте. Наконец, время, чтобы изучить, что такое закрепление и почему оно необходимо. @@ -731,7 +731,7 @@ fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll Используя async/await, можно эргономично работать с футурами в полностью асинхронном режиме. Однако, как мы узнали выше, футуры ничего не делают, пока их не вызовут. Это означает, что нам нужно в какой-то момент вызвать `poll`, иначе асинхронный код никогда не будет выполнен. -Запуская одну футуры, мы можем вручную ожидать ее исполнения в цикле, [как описано выше](#ожидание-futures). Однако этот подход очень неэффективен и непрактичен для программ, создающих большое количество футур. Наиболее распространённым решением этого является создание глобального _исполнителя_ (executor), который отвечает за опрос (polling) всех футур в системе, пока они не завершатся. +Запуская одну футуры, мы можем вручную ожидать ее исполнения в цикле, [как описано выше](#waiting-on-futures). Однако этот подход очень неэффективен и непрактичен для программ, создающих большое количество футур. Наиболее распространённым решением этого является создание глобального _исполнителя_ (executor), который отвечает за опрос (polling) всех футур в системе, пока они не завершатся. #### Исполнитель @@ -830,7 +830,7 @@ pub struct Task { [_trait object_]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html [_dynamically dispatched_]: https://doc.rust-lang.org/book/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch -[разделе о закреплении]: #Закрепление +[разделе о закреплении]: #pinning Чтобы разрешить создание новых структур `Task` из футур, мы создаём функцию `new`: