可重复使用的同步 HttpClient 请求
Reusable Sync HttpClient Request
我需要一个可重复使用的函数来发出 HTTP 请求并等待其完成,然后再将响应作为字符串返回。
这是主要功能:
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;
}
我试过用 async
和 await
在 listen
中定义函数,在没有 onDone()
的情况下在 listen
中返回 contents
,但输出是一样的:
// 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.
编辑2:
提交this issue on GitHub后,我发现HttpClient
的实例有一个连接池并默认保持持久连接,这使Dart VM保持活动状态。请查阅问题页面以了解可能的解决方案。
可能是response.transform
之前的await
造成的。
你可能想要像
这样的东西
return response.transform(UTF8.decoder).join('');
暂停与makeRequest()
无关。 Dart VM 似乎在退出前等待着什么。添加 exit(0);
作为 main()
中的最后一行使应用程序立即退出。
更新
上的回复
This is caused by the HttpClient instance having a connection pool
which can keep the Dart VM alive. There are two ways of avoiding this:
1) Close the HttpClient explicitly
2) Use non-persistent connections
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);
}
我需要一个可重复使用的函数来发出 HTTP 请求并等待其完成,然后再将响应作为字符串返回。
这是主要功能:
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;
}
我试过用 async
和 await
在 listen
中定义函数,在没有 onDone()
的情况下在 listen
中返回 contents
,但输出是一样的:
// 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.
编辑2:
提交this issue on GitHub后,我发现HttpClient
的实例有一个连接池并默认保持持久连接,这使Dart VM保持活动状态。请查阅问题页面以了解可能的解决方案。
可能是response.transform
之前的await
造成的。
你可能想要像
这样的东西 return response.transform(UTF8.decoder).join('');
暂停与makeRequest()
无关。 Dart VM 似乎在退出前等待着什么。添加 exit(0);
作为 main()
中的最后一行使应用程序立即退出。
更新
上的回复This is caused by the HttpClient instance having a connection pool which can keep the Dart VM alive. There are two ways of avoiding this:
1) Close the HttpClient explicitly
2) Use non-persistent connections
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);
}