Когда мне нужно указать тип возвращаемого значения асинхронной функции в качестве будущего объекта? - PullRequest
0 голосов
/ 10 июня 2019

Я проходил урок по асинхронному программированию с помощью dart, но по какой-то причине я немного запутался. Я думаю, что я понимаю концепции того, как вы должны использовать асинхронную функцию, когда это может потребовать некоторого времени и поэтому вместо блокировки и замораживания вашего приложения вы используете асинхронную функцию, чтобы выполнялись следующие блоки кода или методы, и когда выполнялась асинхронная функция сделано или готово выполняется (Пожалуйста, дайте мне знать, если мое понимание неверно)

Тем не менее, я не понимаю, что такое будущее <>. Я понял, что его можно использовать в качестве возвращаемого типа асинхронной функции, потому что, по сути, вы говорите, что функция возвращает объект будущего на данный момент, но давайте вернемся к нему после его завершения. Но мой инструктор смутил меня, иногда у нее было будущее в качестве возвращаемого типа, а в другой раз она не ставила его, и они оба были асинхронными функциями. Так что теперь я пытаюсь понять, когда необходимо явно указать тип возвращаемого значения Future, даже если он недействителен? Также не просто использовать асинхронное и ждать, пока функция уже создаст объект будущего независимо от ?? Любое разъяснение высоко ценится, спасибо.

Ответы [ 2 ]

2 голосов
/ 10 июня 2019

Да, использование ключевого слова async заставит функцию автоматически возвращать Future.

Всегда лучше явно объявить тип возвращаемого значения функции даже для пустых функций, если нет, компилятор интерпретируетфункция как имеющая динамический тип возврата.

Читателю также будет легче / легче узнать тип возвращаемого значения функции.

Кроме того, вам необходимо обернуть ваш объект в Future в асинхронную функцию, например:

Future<Object> getObject() async {
  final object = await timeConsumingTask();
  return object;
}

Если вы напишите это без упаковки:

Object getObject() async {
  final object = await timeConsumingTask();
  return object;
}

Компилятор выдает ошибку: Functions marked 'async' must have a return type assignable to 'Future'.

Для функций void, кажется, чтовам не нужно переносить возвращаемый тип в Future, поэтому что-то вроде этого хорошо:

void doSomething() async {
  await timeConsumingTask();
  print('done');
}
0 голосов
/ 10 июня 2019

Давайте рассмотрим метод gatherNewsReports(), который возвращает только Future<String>.Строковое значение Future из gatherNewsReports.Реализация gatherNewsReports.

// Imagine this is a slow method. Takes time to finish
Future<String> gatherNewsReports() => Future.delayed(Duration(seconds: 1), () => news);

Мы рассмотрим все возможные комбинации вызова метода с Future и async.Метод, который я собираюсь сделать, называется getDailyNewsDigest

Option-1:

Одно из определений метода может быть таким, как в Future и async, указанных в вызове метода:

Future<String> getDailyNewsDigest() async {
  var str = await gatherNewsReports();
  print(str);
  return str;
}

Помните, что gatherNewsReports(), который возвращает Future<String>.Мы просто возвращаем то, что gatherNewsReports возвращает.

Использование:

main() async {
  await getDailyNewsDigest();
  print('call done');
}

Выход:

<gathered news goes here>
call done

Комментарии: Это кажется прямым.Вы просто вызываете метод и ждете его.Помните, что мы используем ключевое слово await при вызове getDailyNewsDigest из метода main.Таким образом, если мы не передадим 1 second, т. Е. Продолжительность, для которой требуется Future.Если мы не использовали ключевое слово await, то выходная последовательность будет инвертирована.

Опция 2

Одно определение метода может быть таким, как для заданных Future и async НЕ указано в вызове метода:

Future<String> getDailyNewsDigest() {
  var str = await gatherNewsReports();
  print(str);
  return str;
}

Это недопустимо, потому что вы не можете вызвать метод с await, в данном случае gatherNewsReports. Это недопустимо .

Option-3

Мы определяем метод может быть с Future NOT GIVEN иasync указано в вызове метода.Поскольку тип возвращаемого значения будет void, мы не будем ничего возвращать ( Примечание: если мы попытаемся вернуть что-либо, кроме Future или void, то получим ошибку ):

void getDailyNewsDigest() async {
  var str = await gatherNewsReports();
  print(str);
}

Это допустимое определение метода.Теперь, поскольку метод объявлен как void, мы не можем await для метода main.Обновленный метод main.

main() async {
  getDailyNewsDigest(); // We can't await on it since return is void
  print('call done');
}

Вывод:

call done
<gathered news goes here>

Как видно, метод getDailyNewsDigest не вызывается без awaitвыход обратный.Мы больше не ждем завершения getDailyNewsDigest.

Option-4

Мы определяем, что метод может быть с Future<Void> вместо Future<String> и async, указанными в методеcall:

Future<void> getDailyNewsDigest() async {
  var str = await gatherNewsReports();
  print(str);
  return;
}

Теперь в нашем основном методе мы можем снова использовать ключевое слово await для вызова getDailyNewsDigest.

main() async {
  await getDailyNewsDigest(); // We can await on it since return is Future<Void> but don't care on the output since it returns nothing
  print('call done');
}

Это 4 комбинации, которые я могу придумать.

Что касается этого:

Но мой инструктор немного смутил меня, иногда у нее было будущее в качестве возвращаемого типа, а в другой раз она не ставила его, и они оба были асинхроннымиfunctions.

Объявление метода с помощью либо Future означает, что вы можете ожидать его, а объявление с помощью void означает, что вы не можете await в нем.Конечно, вы можете не await на Future, если вы не хотите ничего делать с выводом Future.Если вы пишете свой код таким образом, что не хотите, чтобы кто-либо зависел от вывода метода, т. Е. Future, который мы в противном случае возвратили бы из метода, будет обрабатывать d сам по себе, все, о чем мы заботимся, это увольняем и продолжаем нашу работу ;в этом случае мы должны определить наш метод с типом возврата void.

...