简体   繁体   English

如何在NodeJS应用程序中创建某种上下文,我可以从那里调用的所有函数都可以访问?

[英]How to create some kind of context in a NodeJS application, I can access in all functions I call from there?

In Meteor (a NodeJS Framework), there is a function called Meteor.userId() that always returns the userId that belongs to the current session as long as I am in a function that was original called from a Meteor Method . 在Meteor(一个NodeJS框架)中,有一个名为Meteor.userId()的函数,只要我处于从Meteor Method最初调用的函数中,它始终会返回属于当前会话的userId。

The Meteor.userId() function utilizes meteors DDP?._CurrentInvocation?.get()?.connection . Meteor.userId()函数利用流星DDP?._CurrentInvocation?.get()?.connection So somehow this "Magic line" gets my current DDP connection. 因此,这条“魔术线”以某种方式获得了我当前的DDP连接。 This also works when burried deep inside of callbacks. 当埋藏在回调的内部时,这也适用。

So somehow meteor sets a context that it refers to. 因此,流星以某种方式设置了它所指的上下文。 I also want to do this kind of trick for another API that doesn't utilize meteors DDP but is a plain HTTP Api. 我还想为另一个不使用流星DDP但是普通HTTP Api的API做这种技巧。

What I want to do: 我想做的事:

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);
    })
}

I can wrap the call to answerRequest if this is necessary. 如果有必要,我可以将调用包装为answerRequest

I don't know how Meteor does it, but it doesn't look like magic. 我不知道流星是如何做到的,但是看起来并不像魔术。 It looks like Meteor is a global object ( window.Meteor in the browser or global.Meteor in Node.js) that has some functions that refer to some stateful object that exists in the context where they were defined. 它看起来像Meteor是一个全局对象( window.Meteor在浏览器或global.Meteor在Node.js的),有一些功能是指存在于他们被定义的上下文中的一些状态的对象。

Your example could be achieved by having answerRequest (or whatever function calls answerRequest , or whatever you want) call a setRequestContext function that sets the state that will be returned by getRequestContext . 您的示例可以通过让answerRequest (或任何调用answerRequest函数,或您想要的setRequestContext函数)调用setRequestContext函数来实现,该函数设置将由getRequestContext返回的状态。 If you wanted, you could have an additional function, clearRequestContext , that cleans up after request is over. 如果需要,可以有一个附加函数clearRequestContext ,该函数在请求结束后会清除。 (Of course, if you have async code you'll need to take care that the latter isn't called until any code that needs that data has finished running.) (当然,如果您有异步代码,则需要注意,直到所有需要该数据的代码运行完毕后,才会调用后者。)

This is rudimentary, but it might look something like the below snippet. 这是基本的,但可能看起来像下面的代码片段。 window.Framework does not need to be defined in the same file as the rest of the code; window.Framework不需要与其余代码一起在同一文件中定义; it just needs to be initialized before answerRequest is called. 它只需要在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%} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM