我需要一个可重用的函数来发出HTTP请求并在将响应作为String返回之前等待它完成。
这是主要功能:
main() async {
var json;
json = await makeRequest('https://...');
print(json);
print('*** request complete ***');
}
(第一种情况)这是发出HTTP请求的可重用函数:
makeRequest(String url) async {
var request = await new HttpClient().postUrl(Uri.parse(url));
// Includes the access token in the request headers.
request.headers.add(...);
// Waits until the request is complete.
var response = await request.close();
await for (var contents in response.transform(UTF8.decoder)) {
return contents;
}
}
这按预期工作,输出为:
// Response contents as a String...
*** request complete ***
(第二种情况)然后我尝试这样做但是没有用:
makeRequest(String url) async {
var request = await new HttpClient().postUrl(Uri.parse(url));
// Includes the access token in the request headers.
request.headers.add(...);
// Waits until the request is complete.
var response = await request.close();
var json = '';
await response.transform(UTF8.decoder).listen((contents) {
// At first I tried to return contents here, but then I added onDone().
json += contents;
}, onDone: () {
return json;
});
return json;
}
我尝试使用listen
和async
在await
内定义函数,在contents
内listen
返回onDone()
,但不是// Empty line.
*** request complete ***
// Waits a few seconds doing nothing before terminating...
输出是相同的:
Future<String> twitterRequest(String url) async {
var request = await new HttpClient().postUrl(Uri.parse(url));
// Includes the access token in the request headers.
request.headers.add(...);
// Waits until the request is complete.
var response = await request.close();
var json = '';
await for (var contents in response.transform(UTF8.decoder)) {
json += contents;
// Putting a break here produces the same output but terminates immediately (as wanted).
}
return json;
}
有谁知道为什么第二种情况不起作用?
修改
更新代码后,它会执行它应该执行的操作,但在终止执行之前需要几秒钟:
// Prints response contents...
*** request complete ***
// Takes a few seconds before execution terminates. With the break the code terminates immediately.
输出:
HttpClient
EDIT2:
提交this issue on GitHub后,我发现library(reshape2)
library(ggplot2)
demo <- data.frame(cbind(
ID = c(1:10),
X = c(5.00, 1.03, 1.26, 2.03, 0.99, 4.24, 5.00, 5.00, 2.83, 5.00),
Y1 = c(0.17, 0.84, 0.79, 0.59, 0.85, 0.22, 0.17, 0.17, 0.40, 0.17),
Y1_lci = c(0.16, 0.81, 0.76, 0.56, 0.82, 0.22, 0.16, 0.16, 0.39, 0.16),
Y1_uci = c(0.18, 0.87, 0.82, 0.61, 0.88, 0.23, 0.18, 0.18, 0.41, 0.18),
Y2 = c(0.14, 0.85, 0.80, 0.59, 0.86, 0.20, 0.14, 0.14, 0.38, 0.14),
Y2_lci = c(0.11, 0.83, 0.77, 0.54, 0.84, 0.16, 0.11, 0.11, 0.33, 0.11),
Y2_uci = c(0.19, 0.88, 0.83, 0.64, 0.88, 0.25, 0.19, 0.19, 0.44, 0.19)))
demo.melt <- melt(demo, id.vars=c("ID", "X"), value.name="value", variable.name="var")
的实例具有连接池并默认保持持久连接,这使Dart VM保持活动状态。请查阅问题页面以了解可能的解决方案。
答案 0 :(得分:2)
这可能是由await
之前的response.transform
引起的。
您可能需要类似
的内容 return response.transform(UTF8.decoder).join('');
暂停与makeRequest()
无关。 Dart VM似乎在它退出之前等待一些东西。在exit(0);
中添加main()
作为最后一行会立即退出应用程序。
<强>更新强>
的回复这是由具有连接池的HttpClient实例引起的 这可以让Dart VM保持活力。有两种方法可以避免这种情况:
1)明确关闭HttpClient 2)使用非持久连接
import 'dart:async';
import 'dart:convert' show UTF8;
import 'dart:io';
Future main() async {
await makeRequest();
print('end of main');
}
Future makeRequest() async {
var client = new HttpClient();
var request = await client.postUrl(Uri.parse('https://example.com'));
var response = await request.close();
var contents = await response.transform(UTF8.decoder).join();
print(contents);
client.close(); // Close the client.
}
import 'dart:async';
import 'dart:convert' show UTF8;
import 'dart:io';
Future main() async {
await makeRequest();
print('end of main');
}
Future makeRequest() async {
var request = await new HttpClient().postUrl(Uri.parse('https://example.com'));
request.persistentConnection = false; // Use non-persistent connection.
var response = await request.close();
var contents = await response.transform(UTF8.decoder).join();
print(contents);
}