我正在尝试通过Dart从this link获取数据。由于我正在使用dart:io
库的基于HttpClientResponse
的实例来收听从上述链接获得的数据,因此,我认为StringBuffer
的实例将是捕获接收到的数据的最佳选择。这将帮助我以增量方式构建响应字符串。但是似乎我没有正确使用StringBuffer
,因为最后响应字符串(存储在receivedBuffer
中)仍然为空。
代码:
import 'dart:io';
import 'dart:convert';
void main() async
{
StringBuffer receivedBuffer = new StringBuffer("");
String url = "https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty";
HttpClient client = new HttpClient();
HttpClientRequest request = await client.getUrl(Uri.parse(url));
HttpClientResponse response = await request.close();
print("[info] Fetch successful. Proceeding to transform received data ...");
response.transform(utf8.decoder).listen((contents) => receivedBuffer.write(contents));
print("[info] Done. Contents:\n");
print(receivedBuffer);
}
输出:
[info] Fetch successful. Proceeding to transform received data ...
[info] Done. Contents:
此外,如果我要写receivedBuffer.write(contents)
,那么除了print(contents)
,所有
所需的数据将按预期打印。但是,在尝试将contents
写入recievedBuffer
时,似乎receivedBuffer
甚至没有被更新过一次。
我读了this article,并尝试将我的代码中存在的答案纳入其中。确切地说,我使用了Completer
实例来解决我的问题,但这没有帮助。
上面提供的代码有什么问题?
答案 0 :(得分:1)
您不是在等待流完成。
在listen
调用中,您为流事件设置了一个接收器,但您不必等待事件到达。
您可以在onDone
调用中添加一个listen
参数,然后在其中进行操作,但是更有可能您只想在这里等待它,然后我建议:
await response.transform(utf8.decoder).forEach(receivedBuffer.write);
调用forEach
时通常要使用listen
,但不记得返回的订阅。或者使用await for
:
await for (var content in response.transform(utf8.decoder)) {
receivedBuffer.write(content);
}
(在大多数情况下,它对应于forEach
调用)。