创建一个 Future 块直到完成

Jan*_*ert 6 dart

是否可以阻止返回 future 的函数调用?

\n\n

我的印象是调用.then()可以做到这一点,但这不是我在输出中看到的。

\n\n
print("1");\nHttpRequest.getString(url).then((json) {\n  print("2");\n});\nprint("3");\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在输出中看到的是:

\n\n
1\n3\n2\n
Run Code Online (Sandbox Code Playgroud)\n\n

getString方法没有async允许我执行的方法await,并且then在任何情况下都会异步执行。

\n\n
  static Future<String> getString(String url,\n      {bool withCredentials, void onProgress(ProgressEvent e)}) {\n    return request(url, withCredentials: withCredentials,\n        onProgress: onProgress).then((HttpRequest xhr) => xhr.responseText);\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

如何使其阻塞,而不在步骤 3 之前放置无限 while 循环等待步骤 2 完成(并不是说由于 Dart 的单线程性质,它无论如何都会工作)?

\n\n

上面的 HttpRequest 加载一个config.json文件,该文件决定应用程序中的所有内容如何工作,如果在文件加载完成之前完成对配置中字段的请求config.json,则会导致错误,因此我需要等到文件加载完成后再进行允许在类的字段上调用 ​​getter,或者 getter 需要等待文件的一次性加载config.json

\n\n

更新,这就是我在 G\xc3\xbcnter 建议我使用之后最终使其工作的方法Completer

\n\n
@Injectable()\nclass ConfigService {\n\n    Completer _api = new Completer();\n    Completer _version = new Completer();\n\n    ConfigService() {\n\n        String jsonURI =\n            "json/config-" + Uri.base.host.replaceAll("\\.", "-") + ".json";\n        HttpRequest.getString(jsonURI).then((json) {\n\n            var config = JSON.decode(json);\n            this._api.complete(config["api"]);\n            this._version.complete(config["version"]);\n\n        });\n    }\n\n    Future<String> get api {\n        return this._api.future;\n    }\n\n    Future<String> get version {\n        return this._version.future;\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我使用的地方ConfigService

\n\n
 @override\n ngAfterContentInit() async {\n\n   var api = await config.api;\n   var version = await config.version;\n\n   print(api);\n   print(version);\n\n } \n
Run Code Online (Sandbox Code Playgroud)\n\n

现在我获得了类似阻塞的功能,但实际上并没有阻塞。

\n

Gün*_*uer 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.
Run Code Online (Sandbox Code Playgroud)

异步调用只是安排代码以供稍后执行。它将被添加到事件队列中,当处理它之前的任务时,它本身将被执行。安排异步调用后,同步代码 `print("3") 将继续。

在您的情况下HttpRequest.getString(),安排对服务器的调用并注册(json) { print("2")为回调,以便在服务器的响应到达时调用。在响应到达之前,应用程序的进一步执行不会停止,但没有办法做到这一点。相反,同步代码会继续执行 ( print("3"))。如果当前执行的同步代码到达末尾,则下一个计划任务将以相同的方式处理。

then()安排代码在完成(json) { print("2"); }后执行getString()

等待

async只是await让异步代码看起来更像同步代码,但在其他方面它是完全相同的,并且将在幕后翻译为xxx.then((y) { ... }).