使用continuation-local-storage时如何解决promise?

时间:2019-06-25 09:04:07

标签: javascript node.js promise continuation-local-storage

continuation-local-storage似乎也用于表达。

但是,由于上下文完全丢失,非常基本的用法对我来说不起作用!

var createNamespace = require('continuation-local-storage').createNamespace;
var session = createNamespace('my session');


async function doAsync() {
    console.log('Before getting into the promise: ' + session.get('test'));
    await Promise.resolve();
    console.log('*in* the promise: ' + session.get('test'));
}

session.run(() => {
    session.set('test', 'peekaboo');
    doAsync();
});

导致:

$ node server_test.js 
Before getting into the promise: peekaboo
*in* the promise: undefined

我做错了什么吗?还是CLS完全坏了? 还是图书馆坏了? 如果不符合承诺,是否还有其他概念可以作为threadLocal存储来以适当的方式实现多租户?

2 个答案:

答案 0 :(得分:0)

cls-hooked似乎运行良好,尽管该库(与前一个库一样)的更新时间是两年前...

如果某人还有其他更健壮的方法来实现多租户的线程本地状态,请分享!

答案 1 :(得分:0)

您试图在多个函数之间维护共享状态,然后这些函数将异步执行。这在JS中很常见,这种语言本身提供了一种非常简单但功能强大的机制:即使外部函数已经完成执行,您也可以从内部函数访问外部函数的变量:

 (function closured() {
    let shared = { /*...*/ };

    function inner() {
      console.log( shared );
    }
    setTimeout(inner);
  })();

现在,尽管它起作用了,但对于大型应用程序却无法很好地扩展:访问该状态的所有函数都必须在一个函数内部,因此该文件确实被炸毁。您正在使用的库正在尝试解决此问题,它们还使用闭包来维护异步调用之间的状态:当您注册异步回调时,状态存储在函数中,然后回调本身将被包装到恢复状态的回调中:

   let state;

   function setTimeoutWithState(cb, time) {
      const closured = state;
      setTimeout(() => {
        state = closured;
        cb();
      }, time);
  }

  state = 1;
  setTimeoutWithState(() => console.log(state), 1000);

  state = 2;
  setTimeoutWithState(() => console.log(state), 500);

现在,库只需要用这种方式包装每个异步回调,然后您就可以轻松地维护状态,不是很好吗?可以肯定的是,但是向每个回调添加代码确实要花很多钱(因为JS大量利用了回调)。