Доступ к контексту запроса в любом месте

Я использую Express, и мне нужно получить доступ к некоторым данным, которые он запрашивает (заголовки, файлы cookie и т.д.) каждый раз, когда я использую журнал для отладки и отслеживания моего приложения.

В других языках (например: Java) у меня есть "Контекст потока", где я могу поместить эти данные и, таким образом, получить доступ к нему, когда я что-то записываю. Но с NodeJS нет такой вещи, насколько я знаю, потому что у нас есть только один поток.

Я пытаюсь избежать передачи переменной req в каждой функции, чтобы я мог записывать эту информацию.

Есть ли функция node или expressjs, которая позволяет мне получать данные в любом месте?

Ответ 1

Тот факт, что JavaScript является однопоточным, не является ограничением и не препятствует использованию "Контекста потоков" в качестве средства для использования "универсально доступного состояния". Проблемы начнутся, как только будут выполнены асинхронные вызовы, и состояние больше не соответствует тому, что вы намереваетесь сделать.

Это одна из причин, почему глобальное состояние считается "дурной привычкой", и вы должны стремиться избегать его (не конкретно при разработке в JavaScript и/или Node...).

Вместо этого вы должны обходить объект, но не req. Вы должны создавать свои объекты или вызывать свои функции таким образом, чтобы экземпляр log, относящийся к каждой цепочке вызовов (начиная с события запроса и через все внутренние вызовы), передавался. Этот экземпляр log должен быть инициализирован любым контекстом, необходимым для ведения журнала, а в вашем случае - данными запроса из оригинала req.

Ответ 2

Посмотрите на Continuation Local Storage, он реализует нечто похожее на контекст потока для асинхронных цепочек вызовов: https://github.com/othiym23/node-continuation-local-storage

Также есть попытки создать асинхронное локальное хранилище как стандартизованную функцию в javascript, но они все еще находятся на очень ранней стадии: предложение TC39 Zone https://docs.google.com/presentation/d/1H3E2ToJ8VHgZS8eS6bRv-vg5OksObj5wv6gyzJJwOK0