я хорошо разбираюсь в гидрологии
Два похожих ключевых слова в 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().