是否有可能在线程中有“线程”本地variables?

我想存储一个variables,在一个调用链中所有的栈帧(自顶向下)共享。 很像Java或C#中的ThreadLocal。

我find了https://github.com/othiym23/node-continuation-local-storage,但它保留了所有我的用例的上下文,似乎你必须修补你正在使用的库来使本地存储,意识到这对我们的代码基本是或多或less是不可能的。

Node中是否真的没有其他选项可用? 可以使用域,堆栈跟踪或类似的东西来获取当前调用链的句柄(id)。 如果这是可能的,我可以写我自己的线程本地实现。

       

网上收集的解决方案 "是否有可能在线程中有“线程”本地variables?"

对的,这是可能的。 托马斯·沃森(Thomas Watson)在NodeConf 2016年奥斯陆节点(NodeConf)上发表了他的Instrumenting Node.js

它使用Node.js跟踪 – AsyncWrap (它最终应该成为公共节点API的一个非常成熟的部分)。 您可以在开源的Opbeat Node代理中看到一个例子,或者更好的办法是查看对话幻灯片和示例代码 。

TLS在一些普通的单线程程序使用全局variables的地方使用,但是在multithreading的情况下这是不合适的。

由于JavaScript没有暴露的线程,全局variables是对你的问题最简单的答案,但使用一个是不好的做法。

您应该使用闭包:只需将所有asynchronous调用包装到一个函数中,然后在其中定义variables。

闭包中创build的函数和callback

(function() ( var visibleToAll=0; functionWithCallback( params, function(err,result) { visibleToAll++; // ... anotherFunctionWithCallback( params, function(err,result) { visibleToAll++ // ... }); }); functionReturningPromise(params).then(function(result) { visibleToAll++; // ... }).then(function(result) { visibleToAll++; // ... }); ))(); 

在闭包之外创build的函数

如果你需要你的variables在请求范围内没有定义的函数中可见,你可以创build一个上下文对象,并将其传递给函数:

  (function c() ( var ctx = { visibleToAll: 0 }; functionWithCallback( params, ctx, function(err,result) { ctx.visibleToAll++; // ... anotherFunctionWithCallback( params, ctx, function(err,result) { ctx.visibleToAll++ // ... }); }); functionReturningPromise(params,ctx).then(function(result) { ctx.visibleToAll++; // ... }).then(function(result) { ctx.visibleToAll++; // ... }); ))(); 

使用上面所有在c()调用的函数的方法获取对同一个ctx对象的引用,但对c()不同调用有自己的上下文。 在典型的用例中, c()将是你的请求处理程序。

绑定上下文到this

你可以通过Function.prototype.call调用它们,将你的上下文对象绑定到被调用的Function.prototype.call

 functionWithCallback.call(ctx, ...) 

…用Function.prototype.bind创build新的函数实例:

 var boundFunctionWithCallback = functionWithCallback.bind(ctx) 

…或使用蓝鸟的.bind类的诺言效用函数

 Promise.bind(ctx, functionReturningPromise(data) ).then( ... ) 

其中的任何一个都会使ctx在你的函数中可用,如下this

 this.visibleToAll ++; 

…但是它并没有比传递上下文有真正的优势 – 你的函数仍然需要注意通过this传递的上下文,如果你没有上下文,你可能会意外地污染全局对象。

现在,我最初问这个问题已经有一年多的时间了,最​​后看起来我们有一个工作解决scheme,以Node.js 8中的Async Hooks的forms出现。

https://nodejs.org/api/async_hooks.html

API仍然是实验性的,但即使如此,看起来已经有一个在本地使用这个新API的Continuation-Local-Storage分支。

https://www.npmjs.com/package/cls-hooked