Ответ 1
Цель do
Ключевое слово for
может использоваться двумя различными способами:
1) В качестве автономного оператора блока:
for 1..5 { say $_ }
2) В качестве модификатора оператора, добавленного в конец инструкции:
say $_ for 1..5;
Когда искомое ключевое слово for
встречается в середине более крупного оператора, оно интерпретируется как вторая форма.
Если вы хотите использовать форму блока внутри более крупного оператора (например, в качестве аргумента функции await
), вы должны префикс его с помощью do
, чтобы рассказать синтаксическому анализатору о том, что вы запускаете оператор блока здесь, и хотите получить возвращаемое значение.
В более общем плане do
гарантирует, что то, что следует за ним, анализируется с использованием тех же правил, которые он будет разбираться, как если бы это был его собственный оператор, и заставляет его предоставлять возвращаемое значение. Таким образом, это позволяет нам использовать любое выражение как выражение внутри более крупного оператора. do if
, do while
и т.д. все работают одинаково.
Объяснение кода
Код, который вы показали...
await do for @files -> $file {
start {
#do somthing ... }
}
... выполняет следующие действия:
- Это петли над массивом
@files
. - Для каждой итерации он использует ключевое слово
start
для планирования асинхронной задачи, которая, по-видимому, что-то делает с текущим элементом$file
. (Переменная$*SCHEDULER
определяет, как задача фактически запускается, по умолчанию использует простой планировщик пула потоков.) - Каждый вызов
start
немедленно возвращаетPromise
, который будет обновляться после завершения асинхронной задачи. -
do for
собирает последовательность всех возвращаемых значений тела цикла (т.е. promises). - Функция
await
принимает эту последовательность как свой аргумент и ждет, пока все promises не будут завершены.
Как "ждать после кода"
Не совсем уверен, что вы имеете в виду здесь. Если вы хотите запомнить promises, но не ждите их только струи, просто сохраните их в массиве:
my @promises = do for @files -> $file {
start {
#do something ... }
}
#other code ...
await @promises;
Нет никаких удобных функций для ожидания всех запланированных/выполняемых задач. Вам всегда нужно отслеживать promises.