假设我们使用配置了超时的http包从dart:io应用程序发出HTTP请求:
dynamic getSomething(String url) async {
try {
var response = await http.get(url).timeout(new Duration(seconds: 30));
return JSON.decode(response.body);
} catch (_) {
return null;
}
}
这里有两个期货,一个由http.get(请求Future)生成,另一个由Future.timeout生成(超时Future)。如果请求未来完成, 它的值被传递到超时Future,而后者又被完成。那很好。
但是,如果http.get在30秒内未完成,则超时未来将完成并抛出TimeoutException。请求Future会发生什么? 肯定有一些与请求Future相关联的状态和内存分配,只是通过运行超时Future来专门清理。更糟糕的是, 如果请求Future在超时后完成,那么该代码仍将执行。具体取消请求是否超时Future的责任 - 在这种情况下,这是不可能的,因为它被埋在包装中 - 或者是否还有一些必须使用的其他机制?
更一般地说,一个永远不会完成的未来最终是否会清理其状态和内存,还是会永远存在?
答案 0 :(得分:2)
当没有对它的引用时,Future会收集垃圾,就像任何其他变量一样。关于Future变量没有任何本质上的不同。例如,它们不是操作系统构造。
在您的http示例中,超时Future是从原始Future链接的,因此如果原始Future完成,那么超时Future也将完成。在相反的情况下,超时触发,http操作将保持对原始未来的引用(其持有对超时未来的引用),直到http操作完成。因此,期货可能泄漏的唯一方法是,如果http请求永远不会返回,但此时您正在泄漏http连接,并且您遇到的问题比泄漏一些期货更大。
请注意,超时Future完成的事实并不意味着存在错误。错误表现不同。错误会导致Future调用catchError()或调用回调。