是否可以阻止返回未来的函数调用?
我的印象就是调用.then()
来做,但这不是我在输出中看到的。
print("1");
HttpRequest.getString(url).then((json) {
print("2");
});
print("3");
我在输出中看到的是:
1
3
2
getString
方法没有async
允许我await
,而then
在任何情况下都是异步执行。
static Future<String> getString(String url,
{bool withCredentials, void onProgress(ProgressEvent e)}) {
return request(url, withCredentials: withCredentials,
onProgress: onProgress).then((HttpRequest xhr) => xhr.responseText);
}
在第3步等待第2步完成之前,如何在不放置无限循环的情况下使其阻塞(不是因为Dart的单线程特性而无论如何它会起作用)?
上面的HttpRequest加载一个config.json
文件,用于确定应用程序中所有内容的工作方式,如果配置中的字段请求在config.json
文件加载完成之前完成,则会导致错误,所以我需要等到文件完成加载之前我才允许在类的字段上调用getter,或者getter需要等待config.json
文件的一次性加载。
更新,这是我在Günter建议使用Completer
之后最终做的工作:
@Injectable()
class ConfigService {
Completer _api = new Completer();
Completer _version = new Completer();
ConfigService() {
String jsonURI =
"json/config-" + Uri.base.host.replaceAll("\.", "-") + ".json";
HttpRequest.getString(jsonURI).then((json) {
var config = JSON.decode(json);
this._api.complete(config["api"]);
this._version.complete(config["version"]);
});
}
Future<String> get api {
return this._api.future;
}
Future<String> get version {
return this._version.future;
}
}
我在哪里使用ConfigService
:
@override
ngAfterContentInit() async {
var api = await config.api;
var version = await config.version;
print(api);
print(version);
}
现在我得到了类似阻塞的功能而没有实际阻止。
答案 0 :(得分:3)
我不确定我理解你想要实现的目标,但在我看来你想要这样做:
myFunction() async {
print("1");
final json = await HttpRequest.getString(url);
print("2");
print("3");
}
答案 1 :(得分:3)
在异步代码完成之前,无法阻止执行。您可以做的是链后续代码,以便在异步代码完成之前不执行它。
链接的一种方式是then
print("1");
HttpRequest.getString(url) // async call that returns a `Future`
.then((json) { // uses the `Future` to chain `(json) { print("2"); }`
print("2");
});
print("3"); // not chained and therefore executed before the `Future` of `getString()` completes.
异步调用只是为后续执行调度代码。它将被添加到事件队列中,当处理它之前的任务时,它本身将被执行。在安排异步呼叫后,同步代码`print(&#34; 3&#34;)将继续。
在您的情况下,HttpRequest.getString()
计划对您的服务器的调用,并将(json) { print("2")
注册为当服务器的响应到达时要调用的回调。应用程序的进一步执行不会停止,直到响应到来并且无法实现这一点。相反,会发生同步代码继续执行(print("3")
)。
如果您当前执行的同步代码到达其结尾,则以相同的方式处理下一个计划任务。
then()
安排在(json) { print("2"); }
完成后执行的代码getString()
。
<强> AWAIT 强>
async
和await
只是让异步代码看起来更像是同步代码,但除此之外它们完全相同,并且会被翻译成xxx.then((y) { ... })
。
答案 2 :(得分:2)
async
语句。换句话说,生产者函数不需要async
,他们只需要返回Future
。
你应该能够做到这一点:
Future consumerFunc() async {
print("1");
var response = await HttpRequest.getString(url);
print("2");
print("3");
}
它应该结果:
1
2
3
注意:await
替换then
方法