Запускать asyn c код синхронно в Dart - PullRequest
1 голос
/ 28 мая 2020

Имеет следующий код:

Future<String> checkPrinter() async {
  await new Future.delayed(const Duration(seconds: 3));
  return Future.value("Ok");
}

String getPrinterStatus() {
  checkPrinter().then((value) {
    return 'The printer answered: $value';
  }).catchError((_) {
    return "Printer does not respond!";
  });
}

void main() {
  print(getPrinterStatus());
}

Результатом является «null», потому что функция getPrinterStatus () возвращается, не дожидаясь завершения checkPrinter (правильно, у меня есть предупреждение, сообщающее, что getPrinterStatus не возвращает string).

Что мне сделать, чтобы getPrinterStatus ждал checkPrinter ()?

Ответы [ 3 ]

1 голос
/ 28 мая 2020
 Future<String> getPrinterStatus() async {
    await checkPrinter().then((value) {
      return 'The printer answered: $value';
    }).catchError((_){
      return "Printer does not respond!";});
  }
0 голосов
/ 28 мая 2020

Не существует такого способа заставить асинхронный c код работать синхронно в Dart. Итак, вам нужно сделать так, чтобы методы asyn c возвращали Future, чтобы можно было дождаться ответа.

Проблема в вашем коде заключается в том, что вы используете метод then, но не не принимайте во внимание, что этот метод возвращает Future, которое вы должны вернуть. Так, например:

String getPrinterStatus() {
  checkPrinter().then((value) {
    return 'The printer answered: $value';
  }).catchError((_){
    return "Printer does not respond!";});
}

Два оператора возврата в этом примере используются для метода, который вы указываете в качестве аргумента для then(), и поэтому не используются для возврата из getPrinterStatus().

Вместо этого then() возвращает Future<String>, которое завершится значением.

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

Future<String> checkPrinter() async {
  await Future.delayed(const Duration(seconds: 3));
  return "Ok";
}

// Just an example that the method could be written like this.
// Future.delayed takes a computation as argument.
Future<String> checkPrinterShorter() =>
    Future.delayed(const Duration(seconds: 3), () => 'Ok');

Future<String> getPrinterStatus() async {
  try {
    return 'The printer answered: ${await checkPrinter()}';
  } catch (_) {
    return "Printer does not respond!";
  }
}

Future<void> main() async {
  print(await getPrinterStatus());
}

Есть некоторые изменения, я думаю, вы должны заметить:

  • Если метод отмечен как async, возвращаемое значение будет автоматически упаковано в Future<Type>, поэтому вам не нужно возвращать Future.value("Ok") но может просто вернуть Ok.

  • Если метод отмечен как async, вы можете использовать await вместо then(). Кроме того, вы можете использовать обычную обработку исключений, поэтому я переписал getPrinterStatus для этого.

0 голосов
/ 28 мая 2020

Ваш getPrinterStatus() не async. main() функция никогда не будет ждать своего выполнения.

Сделайте это async. Выполните рефакторинг вашего main() на что-то вроде

void main() {
  getPrinterStatus().then((value) {
    print(value);
  }).catchError((_){
    return "Printer does not respond!";});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...