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

gwbalxhn  于 11个月前  发布在  Node.js
关注(0)|答案(2)|浏览(155)

在Meteor(一个NodeJS框架)中,有一个名为Meteor.userId()的函数,只要我在一个最初从Meteor Method调用的函数中,它总是返回属于当前会话的userId。
Meteor.userId()函数利用了流星DDP?._CurrentInvocation?.get()?.connection。所以不知何故,这条“魔术线”得到了我当前的DDP连接。这也适用于深埋在回调函数内部的情况。
所以meteor以某种方式设置了它所引用的上下文。我还想为另一个API做这种技巧,它不使用meteor DDP,而是一个普通的HTTP 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

ejk8hzay

ejk8hzay1#

我不知道Meteor是怎么做到的,但它看起来不像魔术。它看起来像Meteor是一个全局对象(浏览器中的window.Meteor或Node.js中的global.Meteor),它有一些函数引用了一些存在于定义它们的上下文中的有状态对象。
您的示例可以通过answerRequest实现(或者任何调用answerRequest的函数,或者任何你想要的)调用一个setRequestContext函数,该函数设置getRequestContext将返回的状态。如果你愿意,你可以有一个额外的函数,clearRequestContext,它在请求结束后进行清理。(当然,如果你有一个CMAC代码,你需要注意的是,在任何需要该数据的代码完成运行之前,不要调用CMAC代码。
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' });

个字符

4zcjmb1e

4zcjmb1e2#

这个问题的解决方案称为AsyncLocalStorage
https://nodejs.org/api/async_context.html#async_context_class_asynclocalstorage,这里有一个例子,它可以如何使用https://docs.nestjs.com/recipes/async-local-storage
它的工作原理基本上类似于其他语言中的线程局部变量。

相关问题