什么是 Future 以及如何使用它?

nvoigt

我收到以下错误:

A value of type 'Future<int>' can't be assigned to a variable of type 'int'

它可能是另一种类型而不是int,但基本上模式是

A value of type 'Future<T>' can't be assigned to a variable of type 'T'

所以...

  • 究竟是什么Future
  • 我如何获得我想要获得的实际价值?
  • 当我只有一个时,我使用什么小部件来显示我的价值Future<T>
nvoigt

如果您熟悉Task<T>orPromise<T>async/await模式,那么您可以直接跳到“如何在 Flutter 中使用带有小部件的 Future”部分。

什么是 Future 以及如何使用它?

好吧,文档说:

表示延迟计算的对象。

那是正确的。它也有点抽象和干燥。通常,函数会返回结果。依次。该函数被调用、运行并返回它的结果。在此之前,呼叫者等待。某些功能,特别是当它们访问硬件或网络等资源时,需要一点时间来完成。想象一下从 Web 服务器加载的头像图片、从数据库加载的用户数据或从设备内存加载的多种语言的应用程序文本。那可能会很慢。

默认情况下,大多数应用程序具有单一的控制流。当此流被阻塞时,例如等待需要时间的计算或资源访问,应用程序就会冻结。如果您足够大,您可能会记住这是标准,但在当今世界,这将被视为错误。即使有些事情需要时间,我们也会得到一些动画。一个微调器,一个沙漏,也许是一个进度条。但是,应用程序如何运行并显示动画,但仍然等待结果?答案是:异步操作。在您的代码等待某事时仍在运行的操作。现在编译器如何知道它是否应该真正停止一切并等待结果,还是继续所有后台工作并仅在此实例中等待?好吧,它无法自己解决这个问题。我们必须告诉 它。

这是通过称为的模式实现的它不是特定于,它在许多其他语言中以相同的名称存在。您可以在此处找到 Dart 的文档

由于需要一些时间的方法不能立即返回,因此它会在完成后返回传递值的承诺。

那就是所谓的Future因此,从数据库加载数字的承诺会返回一段Future<int>时间,而从互联网搜索中返回电影列表的承诺可能会返回Future<List<Movie>>. AFuture<T>将来会给你一个T.

让我们尝试不同的解释:

Future 表示异步操作的结果,可以有两种状态:未完成或已完成。

最有可能的是,因为您这样做并不是为了好玩,您实际上需要Future<T>在您的应用程序中取得进展。您需要显示数据库中的编号或找到的电影列表。所以你要等待,直到结果出来。这是await进来的地方:

Future<List<Movie>> result = loadMoviesFromSearch(input);

// right here, you need the result. So you wait for it:
List<Movie> movies = await result;

但是等等,我们是不是又回到了原点?不是又要等结果了吗?是的,我们确实如此。如果程序没有一些类似顺序​​流的东西,它们将是完全混乱的。但关键是使用await我们告诉编译器的关键字,此时,虽然我们想等待结果,但我们不希望我们的应用程序只是冻结。我们希望所有其他正在运行的操作(例如动画)继续进行。

但是,您只能await在本身标记为async并返回 a 的函数中使用关键字Future<T>因为当你await做某事时,等待的函数不能再立即返回他们的结果。你只能归还你所拥有的,如果你必须等待它,你必须返回一个稍后交付的承诺。

Future<Pizza> getPizza() async {
    Future<PizzaBox> delivery = orderPizza();        

    var pizzaBox = await delivery;

    var pizza = pizzaBox.unwrap();
    
    return pizza;   
}

我们的 getPizza 函数必须等待比萨饼,所以它不是Pizza立即返回,而是返回一个比萨饼将在未来出现的承诺现在,您又可以在await某处使用 getPizza 函数了。

如何将 Future 与 Flutter 中的小部件一起使用?

flutter 中的所有小部件都期望真正的价值。不是一些稍后会出现的价值的承诺。当按钮需要文本时,它不能使用文本稍后出现的承诺。它需要显示的按钮现在,所以它需要的文本现在

但有时,您所拥有的只是一个Future<T>. 这就是FutureBuilder切入点。当你有未来时,你可以使用它,在你等待它时显示一件事(例如进度指示器),并在它完成时显示另一件事(例如结果)。

让我们看一下我们的披萨示例。您想订购比萨饼,在等待时需要进度指示器,希望在交付后查看结果,并且可能在出现错误时显示错误消息:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

/// ordering a pizza takes 5 seconds and then gives you a pizza salami with extra cheese
Future<String> orderPizza() {
  return Future<String>.delayed(Duration(seconds: 5), () async => 'Pizza Salami, Extra Cheese');
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: Scaffold(
        body: Center(
          child: PizzaOrder(),
        ),
      ),
    );
  }
}

class PizzaOrder extends StatefulWidget {
  @override
  _PizzaOrderState createState() => _PizzaOrderState();
}

class _PizzaOrderState extends State<PizzaOrder> {
  Future<String> delivery;

  @override
  Widget build(BuildContext context) {
    return Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          RaisedButton(
            onPressed: delivery != null ? null : () => setState(() { delivery = orderPizza(); }),
            child: Text('Order Pizza Now')
          ),
          delivery == null
            ? Text('No delivery scheduled')
            : FutureBuilder(
              future: delivery,
              builder: (context, snapshot) {
                if(snapshot.hasData) {
                  return Text('Delivery done: ${snapshot.data}');
                } else if(snapshot.hasError) {
                  return Text('Delivery error: ${snapshot.error.toString()}');
                } else {
                  return CircularProgressIndicator();
                }
              })
        ]);
  }
}

这就是你使用 FutureBuilder 来显示你的未来结果的方式。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Python中的__future__是什么,以及如何/何时使用它以及如何工作

Python中的__future__是什么,以及如何/何时使用它以及如何工作

什么是“LocalTestServerContext”以及如何使用它?

什么是定制点对象以及如何使用它们?

什么是Git'--progress'标志以及如何使用它

什么是C#解决方案以及如何使用它?

什么是Java 9开放的模块,以及如何使用它

什么是StringIndexer,VectorIndexer以及如何使用它们?

什么是 Julia 中的回调以及如何使用它们?

pipenv install -e是做什么的,以及如何使用它?

void *是什么意思,以及如何使用它?

什么是Firebase,以及如何在Android中使用它?

什么是docs软件包以及如何使用它?

什么是快速修复窗口以及如何使用它?

符号()=>是什么意思,以及如何使用它?

什么是汇编例程,以及如何在Go中使用它?

RewriteBase是做什么的,以及如何使用它?

什么是Github项目页面以及如何使用它们?

什么是AuthorizationLevel.User以及如何正确使用它?

IP地址0.0.0.1的用途是什么以及如何使用它?

这是什么结构以及如何使用它?

什么是“ .ESD_”文件以及如何使用它

这个符号{$ {`expirydate`}}的含义是什么,以及如何使用它

什么是 react 中的转发 ref 以及我们如何使用它以及为什么使用它。?

什么是“工具”以及如何禁用它?

什么是彗星?为什么使用它以及如何进行处理

什么是响应式网站,为什么使用它们,以及如何开发它们?

为什么要在指令中使用作用域以及如何使用它?

netbeans中的标签或功能?它们是什么以及如何使用它们?