RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1013673
Accepted
CyberDemon
CyberDemon
Asked:2020-08-15 04:25:53 +0000 UTC2020-08-15 04:25:53 +0000 UTC 2020-08-15 04:25:53 +0000 UTC

如何正确使用:Flutter 中的 Futures、Streams 和 Async/Await?

  • 772

亲爱的开发者。几天来我无法理解如何正确使用:Futures、Streams 和 Async / Await。我在官方频道看了视频,但最后我什么也看不懂。如果有人可以向我解释这将是很酷的。因为我经常使用这些类和函数提出问题,但我不明白它们是如何工作的。感谢您的理解))

async-await
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    MiT
    2020-08-15T18:18:04Z2020-08-15T18:18:04Z

    长时间运行的任务在移动应用程序中很常见。在 Flutter/Dart 中,这通过 Future 解决。Future 允许你做异步工作(Async/Await)来释放任何其他不应该被阻塞的流。例如:用户界面(UI)线程。重要的是:

    • Dart 中的代码在单个执行线程中运行。
    • 由于执行线程需要很长时间(阻塞)的代码,程序可能会挂起。
    • 未来对象(futures)表示异步操作的结果,无论是处理还是 I/O,都将在稍后完成。
    • 要暂停执行直到将来完成,请在异步函数中使用 await(或使用 Future API 时使用 then() )。
    • 要捕获错误,请在异步函数中使用 try-catch 构造(或使用 Future API 时的 catchError())。

    异步/等待

    异步/等待

    异步编程是一种并行执行形式,可加快编程循环中的事件链。但是,您不能在所有情况下都使用异步编程。这仅在您寻求简单而不是效率时才有效。对于处理简单和独立的数据,异步编程是一个很好的选择。

    例子:

    import 'package:http/http.dart' as http;
    
    void main() async {
      var response = await http.get('http://google.com'); 
      ... // Наш поток не будет заблокирован, можно выполнять другой код...
      print(response.body); // Как только мы получим ответ мы его отобразим
    }
    

    未来

    Future 是异步操作的结果,可以有两种状态:未完成或已完成。因为异步操作会抛出异常,所以必须对其进行处理。为此,我们可以使用以下方法:

    • 未来.then
    • Future.catchError
    • Future.whenComplete
    • 未来超时

    例子:

    import 'dart:async';
    
    const news = '<gathered news goes here>';
    const moreSecond = Duration(seconds: 120);
    
    Future<void> printDailyNewsDigest() => gatherNewsReports().then(print).catchError(handleError); // Запрашиваем новости, если они приходят отображаем их, если нет обрабатываем ошибку
    
    Future<String> gatherNewsReports() => Future.delayed(moreSecond, () => news); // Получаем новости через 2 минуты (Например через API)
    
    main() {
      printDailyNewsDigest(); // асинхронный метод
      printWinningLotteryNumbers(); // синхронный метод
      printWeatherForecast(); // синхронный метод
      printBaseballScore(); // синхронный метод
    }
    
    printWinningLotteryNumbers() {
      print('Winning lotto numbers: [23, 63, 87, 26, 2]');
    }
    
    printWeatherForecast() {
      print("Tomorrow's forecast: 70F, sunny.");
    }
    
    printBaseballScore() {
      print('Baseball score: Red Sox 10, Yankees 0');
    }
    

    程序输出:

    Winning lotto numbers: [23, 63, 87, 26, 2] 
    Tomorrow's forecast: 70F,sunny. 
    Baseball score: Red Sox 10, Yankees 0 
    <gathered news goes here>
    

    流

    溪流

    Stream 是一系列异步事件。它就像一个异步可迭代(Iterable)——而不是在你请求它时获取下一个事件。Stream 告诉你当它准备好时有一个事件。流有两种类型:单一订阅流和广播流。

    这种方法源于反应式编程(ReactiveX),初学者很难学。简而言之,进入数据流并在其中发生变化的所有内容在其他使用它的地方也会立即发生变化。要了解有关此主题的更多信息,我建议阅读这篇文章。

    例子:

    import 'dart:async';
    import 'package:flutter/material.dart';
    
    class CounterPage extends StatefulWidget {
      @override
      _CounterPageState createState() => _CounterPageState();
    }
    
    class _CounterPageState extends State<CounterPage> {
      int _counter = 0;
      final StreamController<int> _streamController = StreamController<int>(); // Наш поток
    
      @override
      void dispose(){
        _streamController.close(); // Закрываем поток
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Stream version of the Counter App')),
          body: Center(
            child: StreamBuilder<int>(
              stream: _streamController.stream, // Создаем и открываем поток
              initialData: _counter, // Наши данные из потока
              builder: (BuildContext context, AsyncSnapshot<int> snapshot){
                return Text('You hit me: ${snapshot.data} times'); // С помощью StreamBuilder получаем асинхронно данные из потока
              }
            ),
          ),
          floatingActionButton: FloatingActionButton(
            child: const Icon(Icons.add),
            onPressed: (){
              _streamController.sink.add(++_counter); // Изменяем данные в потоке (+1)
            },
          ),
        );
      }
    }
    

    升级版:

    更多细节可以在视频中看到。

    • 14

相关问题

  • 动态导入和导出[重复]

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5