使用Dart,如何使用Future正确返回HttpResponse

时间:2014-08-06 03:21:00

标签: dart dart-io dart-async sqljocky

我正在尝试创建一个非常简单的http服务器来完成一件事。收到HttpRequest后,它会在本地数据库服务器上运行查询,并根据该查询返回一个字符串。

我正在学习Dart,我在抓住期货时遇到了麻烦。我以为我理解了它们,但是这个例子让我相信我真的不知道它们是如何工作的。所以,我不仅在寻找这个问题的解决方案,而且我也很乐意接受任何指示。

注意:这段代码是我一直试图完成的一个非常原始的例子,为了接触Stackoverflow社区,我尽可能地缩短/简化了它,同时保持问题的完整性。

这是我的server.dart代码

import 'dart:io';
import 'package:sqljocky/sqljocky.dart';


final connection = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', password: null, db: 'server1');

main() {

  HttpServer.bind(InternetAddress.ANY_IP_V4, 9090)..then((server) {
    print("serving generic database query on localhost:9090");
    server.listen((request) {
      if (request.method == "GET") {
        request.response.write(getResults());
        request.response.close();
      }
      else {
        request.response.statusCode = HttpStatus.BAD_REQUEST;
      }
    });
  });
}


String getResults() {

  StringBuffer sb = new StringBuffer();
  sb.write("START--");
  connection.query("select name, email, zkey from users")
      ..then((results) {
    results.forEach((row) {
      sb.write(row.toString());
      print(row.toString());
    });
  });

  sb.write("--END");
  print(sb.toString());

  return sb.toString();
}

因此,如果我向此服务器发送请求,则返回" START ---- END"。 服务器打印出预期的查询结果,然后输出" START ---- END"。 这使我相信我的请求响应正在关闭并在查询结果处理完毕之前返回。

因此,无论我是否卷曲localhost:9090 / asdf或实际构建客户端http请求发送者,我都没有得到我期望的响应...这是一个数据库查询结果。

提前致谢

1 个答案:

答案 0 :(得分:7)

"START----END"打印出来'无序'期货的行为在一开始就让大多数开发人员感到困惑 返回未来的connection.query()之类的调用不会立即执行,而是在队列中登记以供以后执行。当前执行的线程一直持续到完成,然后一个接一个地处理队列。

您的代码无效的是您执行异步调用connection.query()并继续,就好像它是同步调用一样。这在Dart中永远不会起作用。当您启动异步执行时,您无法返回同步。 (据我所知,计划中的async / await应该解决这个问题。)

有关详情,请访问dartlang.org The Event Loop and Dart

EDIT测试代码

import 'dart:io';
import 'package:sqljocky/sqljocky.dart';

final connection = new ConnectionPool(host: 'localhost', port: 3306, user: 'root', password: null, db: 'server1');

main() {    
  HttpServer.bind(InternetAddress.ANY_IP_V4, 9090)..then((server) {
    print("serving generic database query on localhost:9090");
    server.listen((request) {
      if (request.method == "GET") {
        getResults()
        .then((result) { 
          print('Result: $result'); 
          request.response.write(result);
          request.response.close();
        });
      }
      else {
        request.response.statusCode = HttpStatus.BAD_REQUEST;
      }
    });
  });
}

Future<String> getResults() { 

  StringBuffer sb = new StringBuffer();
  sb.write("START--");
  return connection.query("select name, email, zkey from users") 
  .then((Result results) => results.toList())
  .then((list) {
    list.forEach((row) {
      sb.write(row.toString());
    });
    sb.write("--END");
  })
  .then((_) => sb.toString());
}

另请参阅Gregs关于此问题的答案如何阅读SqlJocky结果sqljocky querying database synchronously