是否可以在Dart中创建自己的future以从您的方法返回,或者必须始终从dart异步库方法之一返回内置的future返回?
我想定义一个函数,无论它实际上是在执行异步调用(file read/ AJAX /etc)还是只是获取一个局部变量,它总是返回一个Future<List<Base>>
,如下所示:
List<Base> aListOfItems = ...;
Future<List<Base>> GetItemList(){
return new Future(aListOfItems);
}
6条答案
按热度按时间57hvy0tb1#
如果你需要创造未来,你可以使用
Completer
。请参阅文档中的Completer
class。下面是一个例子:但大多数时候,你不需要和一个完成者一起创造未来,就像这个例子:
使用完成符会使代码变得非常复杂,你可以简单地使用下面的代码,因为
then()
也返回一个Future
:或者文件io的示例:
更多提示请参见this blog post。
v9tzhpje2#
您可以简单地使用
Future<T>value
工厂构造函数:avwztpqn3#
从自己的函数返回未来
这个答案总结了你可以做的许多方法。
开始点
你的方法可以是任何东西,但为了这些例子,让我们假设你的方法如下:
目前,您可以像这样使用方法:
但是,您希望方法返回一个
Future
,如下所示:或者能够像这样更实际地使用它:
下面的解决方案都展示了实现这一点的方法。
溶液1:Future()构造函数
最基本的解决方案是使用
Future
的生成式构造函数。我将该方法的返回类型更改为
Future<int>
,然后将旧函数的工作作为匿名函数传递给Future
构造函数。溶液2:将来命名的构造函数
future可以用一个值或一个错误来完成,因此如果你想显式地指定这两个选项中的任何一个,你可以使用
Future.value
或Future.error
命名构造函数。不允许
a
为负值是一个人为的例子,用来展示Future.error
构造函数的用法。如果没有什么会产生错误,那么你可以简单地使用Future.value
构造函数,如下所示:溶液3:异步方法
async
方法自动返回一个Future
,因此您只需标记方法async
并更改返回类型,如下所示:通常情况下,您可以将
async
与await
结合使用,但没有任何规定必须这样做。Dart会自动将返回值转换为Future
。如果您使用的另一个API在函数体中返回一个
Future
,则可以按如下方式使用await
:或者,使用
Future.then
语法也是一样的:溶液4:完成者
使用
Completer
是最低级的解决方案,只有当你有一些上面的解决方案无法涵盖的复杂逻辑时才需要这样做。这个例子类似于上面的命名构造函数解决方案,它除了处理错误外,还以正常的方式完成将来的工作。
关于阻止UI的说明
使用future并不能保证不会阻塞UI(即主隔离),从函数返回future只是告诉Dart在event queue结束时调度任务,如果任务是密集型的,当事件循环调度它运行时,它仍然会阻塞UI。
如果您有一个密集型任务要在另一个分离菌株上运行,则必须生成一个新的分离菌株来运行它。当在另一个分离菌株上完成任务时,它将返回一条消息作为future,您可以将其作为函数的结果传递。
许多标准的Dart IO类(如
File
或HttpClient
)都有将工作委托给系统的方法,因此这些方法不会在UI线程上执行密集的工作,因此这些方法返回的future不会阻塞UI。另见
v6ylcynt4#
@Fox32有正确的答案,此外,我们需要提到完成者的类型,否则我们会遇到异常
Exception received is type 'Future<dynamic>' is not a subtype of type 'FutureOr<List<Base>>
因此完成器初始化将变为
var completer= new Completer<List<Base>>();
6ju8rftf5#
不完全是给定问题的答案,但有时我们可能想
await
一个闭包:我认为它确实含蓄地创造了一个未来,尽管我们没有把它传递到任何地方。
dly7yett6#
这里有一个简单的条件式Future的例子。