Dart HTTP 服务器和 future

标签 dart dart-io dart-async

我正在尝试编写简单的 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/

相关文章:

ajax - 测试dart ajax HttpRequest

flutter - 无法导入svg Flutter

flutter - 为什么我使用键盘时我的小部件会重建

flutter - Flutter 中的 "with"关键字

dart - 内置库 'dart:io' 在 Dartium 上不可用

dart - 如何在 Dart 中读取控制台输入/标准输入?

dart - 如何捕获 dart 聚合物应用程序中所有 Uncaught Error ?

dart - 在Dart中将范围对象保存在范围之外

dart - 在 Windows 上没有 pub 的情况下运行 webdev 错误

dart - 如何用 ZLibEncoder 替换 ZLibDeflater