9

1 つのことを行う非常に単純な http サーバーを作成しようとしています。HttpRequest を受信すると、ローカル データベース サーバーでクエリを実行し、そのクエリに基づいて文字列を返します。

Dart を学んでいて、Futures を理解するのに苦労しています。私はそれらを理解していると思っていましたが、この例では、それらがどのように機能するのか本当にわからないと思います. したがって、私はこの問題の解決策を探しているだけでなく、喜んで受け入れるポインタも探しています.

注: このコードは、私が達成しようとしてきたことの非常に原始的な例であり、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 要求送信者を構築するかに関係なく、期待する応答が得られません...これはデータベース クエリの結果です。

前もって感謝します

4

1 に答える 1

7

"START----END"「順不同」と表示されるのは、最初はほとんどの開発者を混乱させる先物の動作です。
future を返すlike の呼び出しconnection.query()はすぐには実行されませんが、後で実行するためにキューに入れられます。現在の実行スレッドは終了するまで継続され、キューは次々に処理されます。

あなたのコードでうまくいかないのは、非同期呼び出しを行い、connection.query()それが同期呼び出しであるかのように続行することです。Dartでは決して機能しません。非同期実行を開始すると、同期に戻ることはできません。(私が知る限り、計画された async/await がこれを解決するはずです)。

詳細については、dartlang.org を参照してくださいイベント ループと 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") {
        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());
}

この質問に関するグレッグの回答も参照してください SqlJockyの結果を読み取る方法

于 2014-08-06T04:23:59.797 に答える