2016-01-01 2 views
11

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

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

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

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

+2

Есть модули, но честно неявные глобальные переменные запроса ужасны, и вы должны избегать их как можно больше. Только ваш обработчик маршрута должен получить доступ к запросу, а затем передавать только соответствующие биты в нужные им части. –

+1

@ Признать, что это законный вопрос - я думаю, его можно отредактировать, чтобы быть более законным, удалив часть, в которой говорится: «Есть ли модуль», и оставьте ее в «есть функция экспресс или узел»? –

+0

Neuquino - см. @BenjaminGruenbaum комментарий. Пожалуйста, отредактируйте свой вопрос. – Amit

ответ

-2

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

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

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

+6

Я не думаю, что добавление дополнительного аргумента для ВСЕХ моих функций во ВСЕХ моих модулях только для ведения журнала было бы изящным решением. Я знаю, что это будет не так просто, как «var log = require (« myLog »); log.debug ('something') '. Но я пытаюсь добиться чего-то подобного. – Neuquino

+3

Конечно, есть способы - самые тривиальные: домены, зоны, библиотеки обещаний, которые предлагают контекст со связью (например, bluebird), волокна и т. Д. –

+0

@Neuquino, который приведет к жесткому связыванию кода, затруднит тестирование, помешает вам изменить схему ведения журнала (что, если вы хотите больше контекста, но просто 'req'?), И даже не будет работать, как только будет использоваться несколько контекстов (через асинхронный код). – Amit

10

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

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

+0

Это должно быть отмечено как правильный ответ. Правильный ответ, отмеченный в настоящий момент, не отвечает на вопрос правильно. – adam

+0

Будьте осторожны с этой библиотекой, хотя, по-моему, это багги. Я попробовал это, когда делал решение для приложений с несколькими приложениями, и эта библиотека теряла контексты, когда я проводила стресс-тесты. Я закончил тем, что передал контекст запроса в каждой функции, где мне это нужно. На первый взгляд кажется, что это не круто, но явное, чем явное, по-моему. – Alex

Смежные вопросы