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()
, если проверка прошла успешно.
Вы знаете какой-либо способ сделать это?
Спасибо !