两次调用Future之后的NoSuchMethodError

时间:2014-07-23 21:07:55

标签: mongodb dart dart-async

我是一个从MongoDB中获取一些数据的简单方法:

import 'package:mongo_dart/mongo_dart.dart';

Future find() {
  return _db.open().then((_) {
    return _db.collection('foo').find().toList();
  }).then((val) {
    _db.close();
    return val;
  });
}

如果我一次调用此方法,它就可以工作了。连续两次调用它会产生NoSuchMethodError: method not found: 'query'

有人可以解释这个问题吗?

这是完整的堆栈跟踪:

Uncaught Error: The null object does not have a method 'query'.

NoSuchMethodError: method not found: 'query'
Receiver: null
Arguments: [Instance of 'MongoQueryMessage']
Stack Trace: 
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:45)
#1      Db.queryMessage (package:mongo_dart/src/database/db.dart:174:28)
#2      Cursor.nextObject (package:mongo_dart/src/database/cursor.dart:68:29)
#3      Cursor._nextEach (package:mongo_dart/src/database/cursor.dart:102:15)
#4      Cursor.forEach (package:mongo_dart/src/database/cursor.dart:122:14)
#5      Cursor.toList (package:mongo_dart/src/database/cursor.dart:128:24)
#6      DbConnection.find.<anonymous closure> (package:schafkopfer_server/src/schafkopfer/data.dart:49:52)
#7      _rootRunUnary (dart:async/zone.dart:730)
#8      _RootZone.runUnary (dart:async/zone.dart:864)
#9      _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#10     _Future._propagateToListeners (dart:async/future_impl.dart:571)
#11     _Future._complete (dart:async/future_impl.dart:317)
#12     Future.forEach.nextElement (dart:async/future.dart:303)
#13     _rootRunUnary (dart:async/zone.dart:730)
#14     _RootZone.runUnary (dart:async/zone.dart:864)
#15     _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:488)
#16     _Future._propagateToListeners (dart:async/future_impl.dart:571)
#17     _Future._completeWithValue (dart:async/future_impl.dart:331)
#18     _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:393)
#19     _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:23)
#20     _asyncRunCallback (dart:async/schedule_microtask.dart:32)
#21     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:128)

我打开了issue for mongo_dart

2 个答案:

答案 0 :(得分:2)

我相信你正在混合使用异步和同步代码,而这在大多数情况下是行不通的。

方法find返回Future,但您在同步模式下第二次尝试调用find。 您是否可以在find子句内第二次调用then,您的代码将起作用。

main() {
  var mongoTest = new MongoTest();
  mongoTest.find().then((x) {
    print('first find $x');
    mongoTest.find().then((x) => print('second find $x'));
  });
}

所以mongo_dart Db实例可以在关闭后打开,但在这个例子中几乎没有意义。

如果您正在尝试使用Web堆栈的服务器端,我建议您查看现有框架。以雷石东为例。

http://redstonedart.org/2014/07/14/managing-database-connection-with-redstondart/

答案 1 :(得分:1)

根据您在错误报告中链接的Gist,第一次和第二次调用之间的唯一区别是,您使用相同的db实例。我想这个实例在关闭后无法重新打开。每次打开前创建一个新实例应解决问题。

当密集使用数据库连接时,最好保持打开状态。