【问题标题】:how to execute a function only once every X milliseconds?如何每 X 毫秒只执行一次函数?
【发布时间】:2019-03-20 03:50:08
【问题描述】:

我对 javascript 和 node 很陌生,目前正在开发 node.js 应用程序, 该应用使用express和mongoDB,想法是通过webhook,websocket和mqtt监听一些第三方服务并将所有数据存储到mongoDB中。

但我有一个小问题,一些第三方应用程序向我发送数据过于频繁, 例如,mqtt 流每秒发送大约 2 条消息,我每分钟只需要存储其中一条消息。

这是我将 mqtt 实例化到 app.js 中的方式

var mqttHandler = require('./mqtt/mqtt_handler'); //mqtt
var mqttClient = new mqttHandler(); //mqtt
mqttClient.connect(); //mqtt

这是我的 mqttHandler.js:

onst mqtt = require('mqtt');

class MqttHandler {
  constructor() {
    this.mqttClient = null;
    this.host = 'mqtts://host';
    this.username = 'foo'; // mqtt credentials if these are needed to connect
    this.password = 'mypassqword';
    this.port = 8083;
    this.protocol = 'MQTTS';
    this.client = 'bar'
  }

  connect() {
    // Connect mqtt with credentials (in case of needed, otherwise we can omit 2nd param)
    this.mqttClient = mqtt.connect(this.host, {password : this.password, username : this.username, port: this.port});

    // Mqtt error calback
    this.mqttClient.on('error', (err) => {
      console.log(err);
      this.mqttClient.end();
    });

    // Connection callback
    this.mqttClient.on('connect', () => {
      //console.log(`mqtt client connected`);
    });

    // mqtt subscriptions
    this.mqttClient.subscribe('/the_subscription');
    // When a message arrives, console.log it
    this.mqttClient.on('message', function (topic, message) {
      console.log(message.toString())
    });

    this.mqttClient.on('close', () => {
      //console.log(`mqtt client disconnected`);
    });
  }

  // Sends a mqtt message to topic: mytopic
  sendMessage(message) {
    this.mqttClient.publish('mytopic', message);
  }
}

module.exports = MqttHandler;

我正在阅读有关 setInterval 和 setTimeout 的信息,但我不知道如何实现这些以强制给定函数每 X 秒只运行一次(不知道它被调用了多少次)

是否有类似/通用的方式来为 mqtt、webhooks 和/或 websocket 实现此功能?

我从教程中拿了这个关于如何实现 mqtt 的例子,正如我所说,它的工作非常完美,我对 javascript 很陌生。

【问题讨论】:

  • 查看几种节流机制中的任何一种。

标签: javascript node.js express timeout mqtt


【解决方案1】:

使用 setInterval 的一种简单方法是定期设置一个标志,并在发布消息后将其清除。在间隔函数再次设置标志之前忽略任何其他消息。

let readyToPost = false;
setInterval(function(){ readyToPost = true; }, 1000);

在你的函数中:

function connect() {
  if (!readyToPost) return;  // do nothing
  readyToPost = false;
  // rest of your code
}

【讨论】:

  • 试过这种方法,效果很好!请注意,在与我的伙伴交谈后,我们决定使用计数器而不是超时,但这两种方法都很好! (我们都试过了)
【解决方案2】:

还有一个模块mqtt的包装器:

const mqttNow = require('mqtt-now');

const options = {
  host: 'localhost',
  interval: 1000,
  actions: [
    {
      topic: 'public',
      message: 'my message'
    },
    {
      topic: 'random',
      message: () => ( 'random ' + Math.random() )
    }
  ]
}

mqttNow.publish(options);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-04
    • 2019-05-06
    • 1970-01-01
    • 2010-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多