Отношения дротика между ожиданием и завершением - PullRequest
0 голосов
/ 31 января 2020

Следующий пример несколько надуманный, но я пытаюсь понять связь между Completer и будущим, сгенерированным await.

В приведенном ниже примере метод doCal c содержит «await». 'call and a Completer.

Насколько я понимаю, когда дарт попадает в оператор' await ', он немедленно прекращает выполнение метода и возвращает будущее.

Если вы запустите код в dartpad, вы можно увидеть это в выводе. Строка value = Instance of '_Future<int>' печатается немедленно.

Это соответствует моим ожиданиям (т. Е. Ожидание приведет к немедленному возврату метода). Вы можете видеть из строки 'value =', что doCal c вернул Future<int>.

Это также, как и ожидалось.

Проблема, с которой я столкнулся, заключается в том, что последнее линия doCal c также возвращает будущее. В этом случае будущее, сгенерированное завершителем.

Таким образом, кажется, что doCal c возвращает ДВА различных фьючерса.

1) Первый дротик неявно возвращается, когда вызывается await.

2) Второй, который я явно возвращаю с помощью оператора return.

Учитывая, что значение res должно содержать первое будущее (поскольку мы печатаем его значение до того, как будет возвращено будущее завершителя) как получается, что линия res.then ждет, пока не завершится второе будущее.

Кажется, здесь есть какие-то маги c, но я не могу найти какую-либо документацию по ней.

Dart ссылка:

https://dartpad.dev/a42cce3edf01b222206a627e8c8106af

import 'dart:async';
void main() {

  print('hi');
  var res = doCalc();
  print('value = ${res}');

  res.then((result) => print('result = $result'));
}

Future<int> doCalc() async
{
  var done = Completer<int>();

  await Future.delayed(Duration(seconds: 4), 
                 () { 
                   done.complete(10);

                     });

  return done.future;
}

1 Ответ

0 голосов
/ 31 января 2020

Функция async возвращает будущее, которое она создает сама. Он делает это «немедленно», что означает, что он выполняет тело до первой асинхронной задержки (await или await for) перед возвращением будущего.

Любой оператор return внутри функции async используется для завершения возвращенного будущего. Если ваша async функция возвращает Future<int>, то ваши return операторы должны возвращать либо int, либо Future<int>. В первом случае возвращаемое будущее завершается этим целым числом. В последнем случае возвращенное будущее завершится с тем же результатом, что и возвращаемое будущее (назовем это так) , когда возвратное будущее завершится.

Это как если бы return expression; в функции async фактически является return await expression;. В этом примере строку:

return done.future;

можно прочитать как

return await done.future;

, и это должно объяснить поведение, которое вы видите.

...