В чем разница между асинхронным и асинхронным* в Dart?

Flutter

я хорошо разбираюсь в гидрологии

Два похожих ключевых слова в Dartasyncа такжеasync*, могут быть некоторые друзья, которые до сих пор не знают разницы между ними. Теперь краткое введение.

простой ответ

Простой ответ на этот вопрос:

  • asyncвернутьFuture.
  • async*вернутьStream.

async

asyncИзлишне говорить, что любой, кто знает это, знает, что это асинхронный вызов. Когда функция помечена какasync的时候,意味这个方法可能要从事耗时工作,比如说网络请求、处理图片等等。 одеялоasyncПомеченный метод будет использовать возвращаемое значение какFutureУпаковка.

Future<int> doSomeLongTask() async {
  await Future.delayed(const Duration(seconds: 1));
  return 42;
}

мы можем пройтиawaitполучитьFutureвозвращаемое значение в:

main() async {
  int result = await doSomeLongTask();
  print(result); // 等待一分钟后打印 '42'
}

async*

async*Больше, чем*, Плюс*Фактически函数生成器значение. одеялоasync*Отмеченная функция вернет набор возвращаемых значений, которые будут заключены вStreamсередина.async*на самом деле дляyieldЗначение, выдаваемое ключевым словом, представляет собой синтаксический сахар.

Stream<int> countForOneMinute() async* {
  for (int i = 1; i <= 60; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}

Вышеупомянутое на самом деле异步生成器. Мы можем использоватьyieldзаменятьreturnВозвратите данные, потому что это когда наша функция все еще выполняется. В этот момент мы можем использоватьawait forждатьStreamКаждое значение испускается.

main() async {
  await for (int i in countForOneMinute()) {
    print(i); // 打印 1 到 60,一个秒一个整数
  }
}

заявление

На первый взгляд кажется, что пользы от него мало. потому что так как я используюFlutterТак как я почти никогда не использовалasync*. Но теперь, если у нас есть такой спрос, нам нужно запрашивать интерфейс каждую секунду, всего 10 запросов, чтобы увидеть, сколько Maotai осталось в Jingdong.

Первый взгляд на использованиеasyncкод:

  getMaoTai() async{
    for (int i = 0; i <10; i++){
      await Future.delayed(Duration(seconds: 1), ()async {
        MaoTaiData data = await fetchMaoTaiData();
        setState(){
          //更新UI
        };
      });
  }

Приведенный выше код использует цикл, а затем запрашивает интерфейс по очереди каждую секунду и вызывает его после возврата данных.setState()Обновить пользовательский интерфейс. Это приведет к тому, что выsetState()Когда-то, если вы не боитесь проблем с производительностью, вы не боитесь, что продакт-менеджер вас ударит, вы просто так играете. В настоящее времяasync*В игре должно быть:

    Stream<MaoTaiData> getData() async* {
      for (int i = 0; i <10; i++) {
        await Future.delayed(Duration(seconds: 1));
        yield await fetchMaoTaiData();
      }
    }

Таким образом, мы можем использоватьStreamBuilderпод пакетомWidgetНе нужно идти каждый разsetState().