是否可以将异步函数作为Websocket(ws)listerner传递?(node.js和ws-library)
我的websocket必须执行的大多数操作都是AsycnRhous,因此我将异步函数作为回调传递给websocket,并在其中调用wait,这样做可以吗?如果没有,我还有什么选择?是否可以将异步函数作为Websocket(ws)listerner传递?(node.js和ws-library),node.js,express,ws,Node.js,Express,Ws,我的websocket必须执行的大多数操作都是AsycnRhous,因此我将异步函数作为回调传递给websocket,并在其中调用wait,这样做可以吗?如果没有,我还有什么选择? 编辑:这是我的消息侦听器: ws.on('message', async function (message) { if (message instanceof Buffer) { if (currentMode == prot.dataMode) { aw
编辑:这是我的消息侦听器:
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);
}
}
});
如果任何承诺都不可能被拒绝,那么使用async
函数作为处理程序就可以了。你目前的方法会奏效
但这是不现实的。回调处理程序不需要一个异步
函数,如果它生成的承诺被拒绝,那么您将得到一个未处理的PromisejectionWarning
——创建了一个被拒绝的承诺,而该承诺在任何地方都没有被处理。这很难看——未经处理的承诺拒绝被弃用,将来它们会使您的流程崩溃,这是您绝对不希望看到的
如果您使用的是async
函数,那么请确保try/catch
您在内部等待的所有内容,否则,如果等待的内容被拒绝,整个函数将返回被拒绝的承诺,从而导致上述问题。例如:
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);
}
}
});
综上所述,虽然上面的代码在技术上满足了您的需求,但这有点奇怪,因为您正在等待承诺,但在等待承诺之后什么也不做await
是的语法糖。then
,但是如果您没有任何需要在中执行的逻辑。then
(例如在await
之后,或者在异步函数的使用者处),有await
是很奇怪的,您还不如抓住。抓住承诺,并完全省略async
和try
部分,例如:
if (currentMode == prot.dataMode) {
appendData(sessionData,message)
.catch((e) => {
console.log('Error', e);
});
如果您还想确保appendData
仅在最后一次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();
});
}
然后,在
处理程序上的,调用queueAppend
,而不是调用appendData
(同样,不需要async
函数):
你能在你的问题中编辑一些示例代码吗?有没有可能拒绝任何承诺?有一个非常小的机会,但假设没有,这样做可以吗?我已经添加了代码,我希望它是清晰的谢谢你,使用wait的目的是确保在调用另一个appendData之前appendData已完成。应该说的是,最初-请参阅编辑,使用Promise队列以前从未听说过这一点,非常感谢,最后一个问题,因为它们将是多套接字,我应该在哪里声明队列对于每个套接字具有不同的队列?在on(“连接”)内部,您应该在其外部声明队列,以便所有套接字都可以访问同一队列。是的,它是单线程的-如果在处理另一个事件时发生事件,则第二个事件将仅在第一个事件的处理完成后运行,解释器完成当前事件循环队列后。
if (currentMode == prot.dataMode) {
queueAppend(sessionData,message);
}