我有一个直接遍历Mongo集合的服务器方法(即不使用Meteor集合):
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
db.collection("dataRecords").find({}).each(...)
在每个()回调中,我使用不相关集合上的Meteor集合进行读取:
ReportDefs.findOne(...);
执行读取操作时,暂停执行该路径并开始处理下一条记录。这种情况一直在发生。同时,执行在一些暂停的路径上恢复,但这与新记录的处理重叠。结果很糟糕。
所以看起来findOne()在each()回调中不再是同步的吗?
有谁知道如何安全地混合原生Mongo和Meteor系列?我在处理大量记录时试图避免Meteor集合的开销。
答案 0 :(得分:2)
尝试使用Meteor.bindEnvironment
完成“每次回调”。问题来自于流星代码强烈依赖于“当前光纤”的存在(外观here for more details)。这就是findOne
等例程的同步行为甚至可能的原因。因此,您需要提供正在运行的Fiber
,但Meteor.bindEnvironment
已经处理完毕。
有趣的是,因为 Meteor 总是用来警告用户这个问题,例如“流星代码必须始终在光纤内运行”。你没有得到这种类型的消息吗?
答案 1 :(得分:0)
我最终想出来了。如果你这样做
cursor.each()
和wait()在回调中的任何地方,下一个each()回调可以启动,所以你最终并行处理记录,服务器方法可以在一切完成之前返回。
解决方案是在回调中使用cursor.nextObject()来处理下一条记录,只有当你完成处理当前记录时。你应该将它包装在process.nextTick()中,否则你会继续深入到堆栈中。