如何在NodeJS应用程序中创build某种上下文,我可以访问我从那里调用的所有函数?
在Meteor(一个NodeJS框架)中,有一个名为Meteor.userId()
的函数,它总是返回属于当前会话的userId,只要我在一个从Meteor Method
调用的函数中。
Meteor.userId()
函数利用meteorDDP?._CurrentInvocation?.get()?.connection
。 所以不知怎的,这个“魔术线”得到我目前的DDP连接。 这在callback内部深陷时也是有效的。
所以不知何故,meteor设置了它所指的上下文。 我也想为另一个不使用meteorDDP但是一个普通的HTTP API的API做这种技巧。
我想做的事:
doActualStuff = function(param1, param2, param3) { // here, i am burried deep inside of calls to functions // but the function at the top of the stack trace was // `answerRequest`. // I want to access its `context` here but without // passing it through all the function calls. // What I want is something like this: context = Framework.getRequestContext() } answerRequest = function(context) { //do some stuff someFancyFunctionWithCallback(someArray, function(arrayPosition) { aFuncCallingDoActualStuff(arrayPosition); }) }
如果这是必要的,我可以将呼叫包装为answerRequest
。
我不知道meteor是怎么做的,但看起来不像是魔法。 它看起来像Meteor
是一个全局对象(浏览器中的global.Meteor
或Node.js中的global.Meteor
),它具有一些引用某个有状态对象的函数,这些对象存在于定义它们的上下文中。
通过让answerRequest
(或任何函数调用answerRequest
,或任何你想要的)调用一个setRequestContext
函数来设置getRequestContext
返回的状态,就可以实现你的例子。 如果你想,你可以有一个额外的函数clearRequestContext
,在请求结束后清理。 (当然,如果你有asynchronous代码,你需要注意,在需要这些数据的代码已经完成运行之前,不会调用后者。)
这是基本的,但它可能看起来像下面的代码片段。 window.Framework
不需要和其他代码一样在同一个文件中定义, 它只需要在answerRequest
被调用之前被初始化。
let _requestContext = null; window.Framework = { setRequestContext(obj) { _requestContext = obj; }, getRequestContext() { return _requestContext; }, clearRequestContext() { _requestContext = null; }, }; const doActualStuff = function(param1, param2, param3) { const context = Framework.getRequestContext() console.log('Request context is', context); } const answerRequest = function(context) { Framework.setRequestContext(context); setTimeout(() => { try { doActualStuff(); } finally { Framework.clearRequestContext(); } }, 100); } answerRequest({ hello: 'context' });
.as-console-wrapper{min-height:100%}