7

postgres データベース クエリを使用して、次のアクションを決定します。次のコード行を実行する前に、結果を待つ必要があります。これconn.queryで Future が返されますが、コードを別の関数に配置すると、それを非同期にすることができません。

main() {
  // get the database connection string from the settings.ini in the project root folder 
  db = getdb();
  geturl().then((String url) => print(url));
}

Future geturl() {
  connect(db).then((conn) {
    conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
      .then((result) { return result[0].toString(); })
      .catchError((err) => print('Query error: $err'))
      .whenComplete(() {
        conn.close();
      });
  });
}

戻り値を待ちたいだけですgeturl()が、何をしても構いません。すぐに発火します。ここで何が欠けているかを説明するドキュメントの一部を誰かに教えてもらえますか?

4

4 に答える 4

7

ジョンのコメントを詳しく説明するために、async/await を使用してこれを実装する方法を次に示します。(async/await 機能は Dart 1.9 で追加されました)

main() async {
  try {
    var url = await getUrl();
    print(url);
  } on Exception catch (ex) {
    print('Query error: $ex');
  }
}

Future getUrl() async {
  // get the database connection string from the settings.ini in the project root folder 
  db = getdb();
  var conn = await connect(db);
  try {      
    var sql = "select trim(url) from crawler.crawls where content IS NULL";
    var result = await conn.query(sql).toList();
    return result[0].toString();
  } finally {
     conn.close();
  }
}
于 2014-11-16T22:09:18.567 に答える
4

私は、複数の連鎖する先物があるシナリオ (できればすぐに過去のものがawait出てくることを願っています) では、Completer を使用することを好みます。それはこのように動作します:

 Future geturl() {
   final c = new Completer();  // declare a completer.

   connect(db).then((conn) {
     conn.query("select trim(url) from crawler.crawls where content IS NULL").toList()
       .then((result) { 
           c.complete(result[0].toString()); // use the completer to return the result instead
        })
       .catchError((err) => print('Query error: $err'))
       .whenComplete(() {
         conn.close();
       });
   });

   return c.future;  // return the future to the completer instead
 }
于 2014-11-10T17:23:53.737 に答える
3

「ドキュメントはどこですか」という質問に答えるには: https://www.dartlang.org/docs/tutorials/futures/

geturl()関数に「戻り値を待つ」ようにさせようとしていると言いました。Future を返す関数 (前の回答の例のように) は、実行されてすぐに返され、待機しません。実際、データが到着するか、外部プロセスが終了するのを待っている間に、コードが何もしないか、「ブロック」するのを避けるために、Future はまさにそのためのものです。

理解すべき重要な点は、インタプリタが Future の呼び出しthen()または「catchError()」に到達したとき、内部のコードを実行せず、後で Future が「完了」したときに実行されるように脇に置き、その後、次のコードを実行するだけです。

つまり、Dart で Future を使用すると、非線形に実行されるコードのチャンクを設定することになります。

于 2014-11-11T01:52:15.453 に答える