nodejs并发同步执行

时间:2018-02-19 09:02:21

标签: node.js asynchronous websocket synchronization

我有两个WebSockets异步获取数据,每次从套接字获取一些消息时我都会在CompareData中执行一些代码。

问题是CompareData应该同步执行,或者(只有在尚未运行时才会更好)

这是我的代码:

function CompareData(data) {
    console.log('data ', data);
    AsyncFunction();
};
ws1 = new WebSocket(WS1_URL);
ws2 = new WebSocket(WS2_URL);
ws1.on('message', (data) => {
    CompareData(data);
});
ws2.on('message', (data) => {
    CompareData(data);
});
你能帮助我吗?我对NodeJs来说很新鲜

4 个答案:

答案 0 :(得分:1)

Node.js是单线程的。因此,您可能无法像在其他语言中那样在Node程序中获得真正的并发问题。在您的示例中,在任何给定时间最多只能有一个用于CompareData的WebSocket回调。

答案 1 :(得分:0)

您不应该在node.js中进行同步调用,但可以使这些调用顺序进行。见下面的例子可能会有帮助。



var messages = [];
var inProgress = false;

function CompareData(data) {
  return new Promise((resolve, reject) => {
    // do some stuff and resolve
    setTimeout(() => {
      resolve(data);
    }, 1000);
  });
};

const start = async () => {
  if (!inProgress) {
    if (messages.length !== 0) {
      inProgress = true;
      try {
        const data = await CompareData(messages.shift());
        console.log(data);
      } catch (error) {
        console.log(error);
      }
      inProgress = false;
      await start();
    }else{
      console.log('Process Done');
    }
  }
}

const handler = (data) => {
  messages.push(data);
  start();
}

handler(1);
handler(2);
handler(3);
handler(4);

// ws1 = new WebSocket(WS1_URL);
// ws2 = new WebSocket(WS2_URL);
// ws1.on('message', handler);
// ws2.on('message', handler);




答案 2 :(得分:0)

您应该使用一些互斥锁,以避免同时执行compareData的两个异步操作,例如node-mutexmutexify

答案 3 :(得分:0)

我的建议是:

  1. 首先,您需要知道CompareData何时完成。重新组织您的代码以使用promises或回调。如果您使用的是第三方异步功能,我几乎可以肯定他们会在完成时提供一些反馈意见 - 这是异步世界中的必备功能
  2. 在某处添加inProgress = false标志,以便为您提供简单锁定。正如有人发布的那样,JS是单线程的,您可以保证您的代码在运行过程中不会被中断。多亏了你可以使用非常简单的锁而不是多线程中已知的复杂的基于os的互斥锁 LANGS。
  3. ws.on(...)中检查是否设置了inProgress。如果没有,请将其锁定并运行CompareData
  4. 在CompareData完成回调或承诺解析时将 inProgress 设置为false,因此您不再忽略传入的数据。
  5. 如果您可以简单地丢弃数据,则无需使用额外的队列,互斥体等使这种情况复杂化。

    如果你需要全部服务,那么在完成回调被触发后,对传入的数据进行排队并提供下一个数据。

    这基本上是Rahul的建议,但是他使用的功能在当前版本的标准中没有建立,所以如果你没有发现你的代码,就不要使用它。