我正在尝试编写简单的 HTTP 服务器来解析 client.getUrl() 的结果。除了无法写回 http 请求对象(打印到控制台工作正常)之外,我一切正常。
相关代码是:
main() {
HttpServer.bind(InternetAddress.ANY_IP_V4, 4040)
.then((HttpServer server) {
print('listening on localhost, port ${server.port}');
server.listen((HttpRequest request) {
Future loadedContent = loadUrl(furl);
loadedContent.then((content) => print(content));
// loadedContent.then((content) => request.response.write(content));
request.response.close();
print ("response closed");
});
}).catchError((e) => print(e.toString()));
}
问题是 main 函数在我从 Future 得到结果之前就结束了(通过打印在结果之前出现的第二个“响应关闭”来解决这个问题)。有没有办法在主函数中等待结果?
编辑:它与Dart HttpRequest return future有关
我会重写我的代码,但是如果有一种方法可以在 main 函数中等待 getUrl Future ,我会更喜欢它。
编辑:我的 loadUrl
Future loadUrl(String url)
{
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(
Uri.parse("https://*****.tpondemand.com/api"),
"tprealm",
new HttpClientBasicCredentials("*****", "*****"));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest request) {
// Optionally set up headers...
// Optionally write to the request object...
// Then call close.
return request.close();
})
.then((HttpClientResponse response) {
// Process the response.
//print(response.reasonPhrase);
response.transform(UTF8.decoder).listen((contents) {
// handle data
Map parsedMap = JSON.decode(contents);
c.complete(parsedMap);
//req.response.write(parsedMap["Items"][0]);
});
});
return c.future;
}
最后编辑:这是工作代码
import 'dart:io';
import 'dart:async';
import 'package:http_server/http_server.dart';
import 'dart:convert';
final furl = "https://***.tpondemand.com";
Future loadUrlBody(String url) {
final c = new Completer();
HttpClient client = new HttpClient();
client.addCredentials(Uri.parse("https://***.tpondemand.com/api"), "tprealm", new HttpClientBasicCredentials("user", "password"));
client.getUrl(Uri.parse(url))
.then((HttpClientRequest response) => response.close())
.then(HttpBodyHandler.processResponse)
.then((HttpClientResponseBody body) {
c.complete(body);
});
return c.future;
}
main() {
final filter = "/api/v1/Userstories?format=json&where=(Team.Id+eq+111111)&include=[Name,CreateDate,ModifyDate,LastCommentDate]&take=1000";
HttpServer.bind(InternetAddress.ANY_IP_V4, 4040).then((HttpServer server) {
print('listening on localhost, port ${server.port}');
server.listen((HttpRequest request) {
print(request.connectionInfo.remoteAddress);
loadUrlBody(furl + filter).then((content) {
Map parsedMap = content.body;
//print("Map parsed");
request.response.write(parsedMap["Items"]);
request.response.close();
//print("response closed");
}).catchError((e) => print(e.toString()));
});
}).catchError((e) => print(e.toString()));
}
最佳答案
当您的 loadUrl()
返回一个 Future(它可能应该)然后这应该工作
main() {
HttpServer.bind(InternetAddress.ANY_IP_V4, 4040)
.then((HttpServer server) {
print('listening on localhost, port ${server.port}');
server.listen((HttpRequest request) {
loadUrl(furl).then(() {
// loadedContent.then((content) => print(content));
loadedContent.then((content) => request.response.write(content));
request.response.close();
print ("response closed");
});
});
}).catchError((e) => print(e.toString()));
}
更新
您需要修改您的
getData()
或 loadUrl()
方法Future getData(HttpRequest request) { // added return type 'Future' (not necessary)
return dao.findAll().then((value) { // added 'return'
print(value);
});
}
更新 2
Future loadUrl(String url)
{
// final c = new Completer(); // <== commented out
HttpClient client = new HttpClient();
client.addCredentials(
Uri.parse("https://*****.tpondemand.com/api"),
"tprealm",
new HttpClientBasicCredentials("*****", "*****"));
return client.getUrl(Uri.parse(url)) // <== added return
.then((HttpClientRequest request) {
// Optionally set up headers...
// Optionally write to the request object...
// Then call close.
return request.close();
})
.then((HttpClientResponse response) {
// Process the response.
//print(response.reasonPhrase);
return response.transform(UTF8.decoder).listen((contents) { // <== added return
// handle data
Map parsedMap = JSON.decode(contents);
// c.complete(parsedMap); // <== commented out
//req.response.write(parsedMap["Items"][0]);
}).asFuture(); // <== added `.asFuture()`
});
// return c.future; // <== commented out
}
通常,在前面加上
return
就足够了。在每次调用返回 Future 的方法之前,您可以避免使用完成程序。 Completer 仅适用于更复杂的情况(例如,当您从一个方法返回 completer.future 但从其他地方完成它时,例如事件处理程序)。
关于Dart HTTP 服务器和 future ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24244612/