Несколько обработчиков Socket.io для слушателей on, например Express - PullRequest
1 голос
/ 07 мая 2020

Express позволяет разработчику связать несколько функций в качестве обработчиков к одному маршруту. From docs :

Более одной функции обратного вызова может обрабатывать маршрут (убедитесь, что вы указали следующий объект). Например:

app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...')
  next()
}, function (req, res) {
  res.send('Hello from B!')
})

Это замечательно, если разработчик хочет выполнить проверки перед переходом к последней функции. Вот почему промежуточное программное обеспечение - вещь.

Socket.io, с другой стороны, принимает только один обработчик.

От @types/socket.io :

on( event: string, listener: Function ): Namespace;

Это означает, что у меня не может быть промежуточного программного обеспечения, которое зависит от события c. Я знаю о io.use для глобального промежуточного программного обеспечения, и есть возможность иметь промежуточное программное обеспечение для каждого пространства имен, но все, что мне нужно, это для каждого события.


Мои варианты обхода

Вариант 1: try и catch в каждый обработчик событий.

try {
  validateCurrentPlayer(socket);
} catch (e) {
  return handleFailedValidation(socket, e);
}
// ... rest of the code

Pro: читаемый. Con: супер повторяющееся. Это означает, что каждая соответствующая точка входа начинается с одних и тех же 5 строк кода, которые каждый раз делают одно и то же.

И если «промежуточное ПО» возвращает значения, это выглядит так:

let foo: Something;
try {
  [foo] = validateCurrentPlayer(socket);
} catch (e) {
  return handleFailedValidation(socket, e);
}
// ... rest of the code, use foo

Вариант 2: Обычная проверка с условным возвратом

const validation = validate(socket, () => validateCurrentPlayer(socket));
if (validation.error) {
    return;
}
const [foo] = validation.result;

Это validate:

export function validate<T extends (...args: any) => any>(socket: Socket, func: T): {
    error: boolean;
    result: ReturnType<T>;
} {
    let result: ReturnType<T> = null;
    let error = false;
    try {
        result = func();
    } catch (error) {
        handleFailedValidation(socket, error);
    }

    return {
        result,
        error,
    };
}

Как видите, он просто обертывает try и catch.

Pro: не повторяется. Con: Осталось X строк кода, которые нужно скопировать в несколько обработчиков.


Мне не нравятся эти обходные пути.

Я в отчаянии пытаясь найти что-то похожее на подход Express, поэтому я мог бы просто условно позвонить next(), если проверка прошла успешно.

Вы знаете какой-либо способ сделать это?

Спасибо !

...