Если есть вероятность нет отклонения любого из Обещаний, тогда да, с использованием функции async
в качестве обработчика все в порядке. Ваш текущий подход будет работать.
Но это нереально. Обработчик обратного вызова не ожидает async
функции, и если сгенерированное им обещание отклоняет, вы получите UnhandledPromiseRejectionWarning
- отклоненное обещание было создано, которое нигде не обрабатывалось , Это некрасиво - необработанные отказы от Promise устарели, и в будущем они приведут к краху вашего процесса , который вы определенно не захотите.
Если вы используете функцию async
, то обязательно try/catch
все, что у вас внутри await
, потому что в противном случае, если что-то будет ожидаться, будет отклонено, вся функция вернет отклоненное обещание, что приведет к возникновению вышеуказанных проблем. Например:
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
или у потребителя функции async
здесь) странно иметь await
вообще, вы также можете просто .catch
Обещания и полностью исключить части async
и try
, например:
if (currentMode == prot.dataMode) {
appendData(sessionData,message)
.catch((e) => {
console.log('Error', e);
});
Если вы также хотите убедиться, что appendData
будет запускаться только после завершения последнего appendData
вызова, используйте очередь Promise, возможно что-то вроде:
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
):
if (currentMode == prot.dataMode) {
queueAppend(sessionData,message);
}