Is it possible to have “thread” local variables in Node?

前端 未结 3 1056
萌比男神i
萌比男神i 2021-02-05 08:16

I would like to store a variable that is shared between all stack frames (top down) in a call chain. Much like ThreadLocal in Java or C#.

I have found https://github.com

相关标签:
3条回答
  • 2021-02-05 08:40

    TLS is used in some places where ordinary, single-threaded programs would use global variables but where this would be inappropriate in multithreaded cases.

    Since javascript does not have exposed threads, global variable is the simplest answer to your question, but using one is a bad practice.

    You should instead use a closure: just wrap all your asynchronous calls into a function and define your variable there.

    Functions and callbacks created within closure

      (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++;
              // ...
           });
        ))();
    

    Functions created outside of closure

    Should you require your variable to be visible inside functions not defined within request scope, you can create a context object instead and pass it to functions:

      (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++;
              // ...
           });
        ))();
    

    Using approach above all of your functions called inside c() get reference to same ctx object, but different calls to c() have their own contexts. In typical use case, c() would be your request handler.

    Binding context to this

    You could bind your context object to this in called functions by invoking them via Function.prototype.call:

    functionWithCallback.call(ctx, ...)
    

    ...creating new function instance with Function.prototype.bind:

    var boundFunctionWithCallback = functionWithCallback.bind(ctx)
    

    ...or using promise utility function like bluebird's .bind

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

    Any of these would make ctx available inside your function as this:

    this.visibleToAll ++;
    

    ...however it has no real advantage over passing context around - your function still has to be aware of context passed via this, and you could accidentally pollute global object should you ever call function without context.

    0 讨论(0)
  • 2021-02-05 08:48

    Yes, it is possible. Thomas Watson has spoken about it at NodeConf Oslo 2016 in his Instrumenting Node.js in Production (alt.link).

    It uses Node.js tracing - AsyncWrap (which should eventually become a well-established part of the public Node API). You can see an example in the open-source Opbeat Node agent or, perhaps even better, check out the talk slides and example code.

    0 讨论(0)
  • 2021-02-05 08:53

    Now that more than a year has passed since I originally asked this question, it finally looks like we have a working solution in the form of Async Hooks in Node.js 8.

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

    The API is still experimental, but even then it looks like there is already a fork of Continuation-Local-Storage that uses this new API internally.

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

    0 讨论(0)
提交回复
热议问题