将异步函数作为Websocket(ws)listerner传递可以吗? (node.js和ws库)

时间:2019-03-17 02:46:02

标签: node.js express ws

我的websocket要做的大多数动作都是异步的,所以我将异步函数作为回调传递给websocket并在其中调用await,这样做可以吗?如果没有,我还有什么选择?
编辑:这是我的消息监听器:

ws.on('message', async function (message) {
        if (message instanceof Buffer) {
          if (currentMode == prot.dataMode) {
            await appendData(sessionData,message);
          }
          else {
            console.log("error : unexpected message received");
          }
        }
        // if the message is for defining the mode of communication
        //This message is a configuration message
        else {
          message = JSON.parse(message);
          if (message[prot.modeField] == prot.confMode) {
            console.log("conf mode");
            currentMode = prot.confMode;
            await configure(sessionData,message);
          }
          //The following messages will be data
          else if (message[prot.modeField] == prot.dataMode) {
            console.log("data mode");
            currentMode = prot.dataMode;
          }

          else{
            console.log("unknown message structure : ");
            console.log(message);
          }
        }

      });

1 个答案:

答案 0 :(得分:1)

如果没有任何Promises拒绝的机会,则可以,使用async函数作为处理程序是可以的。您当前的方法会起作用。

但这是不现实的。回调处理程序不会期望一个async函数,如果它生成的Promise拒绝了,那么您将得到一个UnhandledPromiseRejectionWarning-一个被拒绝的Promise被创建,没有在任何地方处理。这是丑陋的-未处理的Promise拒绝已被弃用,将来它们会破坏您的过程,您肯定会 不愿意。< / p>

如果您使用async函数,请确保try/catch内部await的所有内容,否则,如果有任何等待的东西拒绝,则整个函数将返回一个被拒绝的Promise,结果以上问题。例如:

ws.on('message', async function (message) {
  if (message instanceof Buffer) {
    if (currentMode == prot.dataMode) {
      try {
        await appendData(sessionData,message);
      } catch(e) {
        console.log('Error', e);
      }
    }
    else {
      console.log("error : unexpected message received");
    }
  }
  // if the message is for defining the mode of communication
  //This message is a configuration message
  else {
    message = JSON.parse(message);
    if (message[prot.modeField] == prot.confMode) {
      console.log("conf mode");
      currentMode = prot.confMode;
      try  {
        await configure(sessionData,message);
      } catch(e) {
        console.log('Error', e);
      }
    }
    //The following messages will be data
    else if (message[prot.modeField] == prot.dataMode) {
      console.log("data mode");
      currentMode = prot.dataMode;
    }

    else{
      console.log("unknown message structure : ");
      console.log(message);
    }
  }
});

所有这些,虽然上面的代码在技术上可以满足您的要求,但这有点奇怪,因为您正在等待Promises,但是在等待它们之后什么也没做。 await.then的语法糖,但是如果您没有任何逻辑,则需要在.then中执行(例如在await之后或在使用者处执行) async的功能),完全有await很奇怪,您也可以只承诺.catch,而忽略async和{{1} }部分组成,例如:

try

如果您想要确保if (currentMode == prot.dataMode) { appendData(sessionData,message) .catch((e) => { console.log('Error', e); }); 仅在最后一次appendData调用完成后运行,请使用Promise队列,也许类似:

appendData

然后,在const appendDataQueue = []; function queueAppend(sessionData, message) { appendDataQueue.push({ sessionData, message }); tryRunNext(); } let active = false; function tryRunNext() { if (active || !appendDataQueue.length) { return; } const { sessionData, message } = appendDataQueue.unshift(); active = true; appendData(sessionData, message) .then(() => { active = false; tryRunNext(); }) .catch((err) => { // handle errors active = false; tryRunNext(); }); } 处理程序中,调用.on而不是调用queueAppend(同样,不需要appendData函数):

async