等待将来完成

时间:2014-11-10 16:49:53

标签: dart dart-async

我使用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 个答案:

答案 0 :(得分:7)

目前你还没有在geturl中回复未来。您必须实际返回您使用的期货:

Future geturl() {
  return connect(db).then((conn) {
    return 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();
      });
  });
}

答案 1 :(得分:6)

详细说明John的评论,以下是使用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();
  }
}

答案 2 :(得分:3)

我更喜欢,在多链式未来的情景中(希望很快就会出现await出现的事情),使用完成者。它的工作原理如下:

 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
 }

答案 3 :(得分:2)

要回答您的“文档在哪里”问题:https://www.dartlang.org/docs/tutorials/futures/

你说你试图让geturl()函数'等待返回的值'。返回Future的函数(如上一个答案中的示例所示)将立即执行并返回,它不会等待。事实上,正是Futures的目的,是为了避免代码在等待数据到达或外部流程完成时无所事事或“阻塞”。

要理解的关键是当解释器在Future上调用then()或'catchError()'时,它不执行内部代码,它将它放在一边以便稍后执行未来'完成',然后继续执行以下任何代码。

换句话说,在Dart中使用Futures时,您正在设置将以非线性方式执行的代码块。