【问题标题】:Meteor delay in iteration through collection通过收集迭代中的流星延迟
【发布时间】:2025-12-07 09:55:02
【问题描述】:

您好,当我迭代集合时,我想在我的流星服务器端方法中建立一个延迟。 Meteor._sleepForMs 方法每次都会导致异常并重新启动我的应用程序。 有哪些方法可以延迟集合迭代?

 Meteor.methods({
 ....
 start: function() {
 let data = Strategy.find({}, {limit: 5}).fetch();
        for (let i = 0; i < data.length; ++i) {
            mqttClient.publish("test", data[i].charge);
            Meteor._sleepForMs(data[i].duration*1000);
        }
  }

【问题讨论】:

  • 因此,您希望您的方法等到迭代完成。对吗?
  • 没有在每次迭代中我想要等待数据[i].duration times

标签: javascript meteor meteor-methods


【解决方案1】:

使用Meteor.setTimeout:

start: function() {
  Meteor.setTimeout(function() {
    let data = Strategy.find({}, {limit: 5}).fetch();
    for (let i = 0; i < data.length; ++i) {
      mqttClient.publish("test", data[i].charge);
    }
  }, 1000);
}

另见why to use that vs vanilla setTimeout()

编辑对于变量:

start: function() {
  let data = Strategy.find({}, {limit: 5}).fetch();
  for (let i = 0; i < data.length; ++i) {
    Meteor.setTimeout(function() {
      mqttClient.publish("test", data[i].charge);
    }, data[i].duration);
  }
}

编辑你可以用 RawCollection 对象做你想做的事,将它的 maxTimeMS 设置为

var rawCollection = Strategy.rawCollection();
// Number.MAX_SAFE_INTEGER should be sufficient time
var cursor = rawCollection.find({}).maxTimeMS(Number.MAX_SAFE_INTEGER );
var myData = fetchCursor(cursor);

var fetchCursor = Meteor.wrapAsync(function 
  fetchCursor (cursor, cb) {
    cursor.each(function (err, doc) {
      if (err) return cb(err);
      if (!doc) return cb(null, { done: true }); // no more documents

      // use doc here.
  });
});

【讨论】:

  • 但我没有等待固定时间,集合有一个持续时间字段,指示延迟时间(data[i].duration)。
  • 这最初会等待 data[i].duration 然后迭代整个集合并发布它。这个想法是等待集合中每一行的 data[i].duration 然后发布它。另一个奇怪的行为是异常:错误:连接 ETIMEDOUT
  • 我不明白最后一种方法
【解决方案2】:

以下是另一种方法,但在 30 次迭代后,它不会延迟持续时间字段时间,而是在 1-10 秒之间迭代随机值。 顺便说一句,我的数据库中有数千个文档。

var Future = Npm.require('fibers/future');
                var future = new Future();
                Meteor.setTimeout(function() {
                    future.return();
                    let d = `${moment(data[i].t).format("YYYY-MM-DD HH:mm:ss")} ${data[i].field}`;
                    mqttClient.publish("test", d);
                }, data[i].duration*1000);
                future.wait();

【讨论】: