Asynchronous Dart,如何在自己的功能中创建未来返回?
是否可以在Dart中创建自己的未来以从方法返回,或者必须始终从Dart异步库方法之一返回内置的未来返回 我想定义一个函数,它总是返回一个Asynchronous Dart,如何在自己的功能中创建未来返回?,asynchronous,dart,future,Asynchronous,Dart,Future,是否可以在Dart中创建自己的未来以从方法返回,或者必须始终从Dart异步库方法之一返回内置的未来返回 我想定义一个函数,它总是返回一个Future,不管它是实际执行异步调用(文件读取/ajax/etc)还是仅仅获取一个局部变量,如下所示: List aListOfItems=。。。; 未来的GetItemList(){ 返回新未来(aListOfItems); } 如果你需要创造未来,你可以使用一个完成器。请参阅文档中的。以下是一个例子: Future GetItemList(){ var c
Future
,不管它是实际执行异步调用(文件读取/ajax/etc)还是仅仅获取一个局部变量,如下所示:
List aListOfItems=。。。;
未来的GetItemList(){
返回新未来(aListOfItems);
}
如果你需要创造未来,你可以使用一个完成器。请参阅文档中的。以下是一个例子:
Future GetItemList(){
var completer=new completer();
//在某些时候,您需要完成未来:
completer.complete(新列表());
返回completer.future;
}
但大多数时候,你不需要用一个完美主义者来创造未来。就像在这种情况下:
Future GetItemList(){
var completer=new completer();
a未来。然后((a){
//在某些时候,您需要完成未来:
完成者。完成(a);
});
返回completer.future;
}
使用补足符,代码可能变得非常复杂。您只需使用以下命令即可,因为then()
也会返回未来的:
Future GetItemList(){
返回未来。然后((a){
//做点什么。。
});
}
或文件io的示例:
Future ReadCommaseOperatedList(文件){
返回file.readAsString().then((text)=>text.split(',');
}
有关更多提示,请参阅。@Fox32有正确的答案。此外,我们需要提及补全符的类型,否则会出现异常
收到的异常是类型“Future”不是类型“FutureOr”的子类型
因此,完成器的初始化将成为
var completer=newcompleter()代码>您只需使用factory构造函数即可:
return Future<String>.value('Back to the future!');
returnfuture.value('backtofuture!');
从您自己的功能返回未来
这个答案是你可以做的许多方法的总结
起点
您的方法可以是任何方法,但为了这些示例,假设您的方法如下所示:
int立方(int a){
返回a*a*a;
}
目前,您可以这样使用您的方法:
int myCubedInt=cubed(3);//27
但是,您希望您的方法返回一个Future
,如下所示:
Future-myFutureCubedInt=cubed(3);
或者能够像这样更实际地使用它:
int mycubedit=wait cubed(3);
下面的解决方案都展示了实现这一点的方法
解决方案1:Future()构造函数
最基本的解决方案是使用Future
的生成构造函数
未来立方(int a){
返回未来(()=>a*a*a);
}
我将方法的返回类型更改为Future
,然后将旧函数的工作作为匿名函数传递给Future
构造函数
解决方案2:未来命名构造函数
期货可以用一个值或一个错误来完成。因此,如果要明确指定这两个选项中的任何一个,可以使用Future.value
或Future.error
命名构造函数
未来立方(int a){
if(a<0){
返回Future.error(ArgumentError(“'a'必须为正”);
}
返回未来值(a*a*a);
}
不允许a
为负值是一个人为的示例,用于说明Future.error
构造函数的用法。如果没有任何东西会产生错误,那么您可以简单地使用Future.value
构造函数,如下所示:
未来立方(int a){
返回未来值(a*a*a);
}
解决方案3:异步方法
async
方法会自动返回一个Future
,因此您可以只标记该方法async
,并更改返回类型,如下所示:
Future cubed(int a)异步{
返回a*a*a;
}
通常您将async
与await
结合使用,但没有任何规定您必须这样做。Dart会自动将返回值转换为未来值
如果您使用的另一个API在函数体中返回未来
,则可以使用等待
,如下所示:
Future cubed(int a)异步{
返回等待立方体远程服务器(a);
}
或者这与使用Future是一样的。然后语法:
Future cubed(int a)异步{
返回cubedOnRemoteServer(a),然后((result)=>result);
}
解决方案4:完成器
使用补码器
是最低级的解决方案。只有当您有一些上面的解决方案无法涵盖的复杂逻辑时,才需要这样做
导入'dart:async';
未来立方(INTA)异步{
最终完成者=完成者();
if(a<0){
completer.completeError(ArgumentError(“'a'必须为正”);
}否则{
完成者。完成者(a*a*a);
}
返回completer.future;
}
此示例类似于上面的命名构造函数解决方案。它处理错误,并以正常方式完成未来
关于阻止UI的注意事项
使用未来并不能保证您不会阻塞UI(即主隔离)。从函数返回未来只是告诉Dart在任务结束时安排任务。如果该任务是密集型的,那么当事件循环计划运行该任务时,它仍然会阻塞该UI
如果要在另一个隔离上运行密集型任务,则必须生成一个新的隔离以在其上运行。当任务在另一台计算机上完成时,它将返回一条消息作为未来消息,您可以将其作为函数的结果传递
许多标准Dart IO类(如File
或HttpClient
)都有删除
flagImage ??= await () async {
...
final image = (await codec.getNextFrame()).image;
return image;
}();