I try to use the experimental module async_hooks
in nodejs.
const Async = require('async_hooks');
const store = {};
const hook = Async.createHook({
init: function (child, _, parent) {
if (store[parent]) {
store[child] = store[parent];
}
},
destroy: function (id) {
delete store[id];
},
});
hook.enable();
let autoInc = 0;
let promise;
function run(index) {
const asyncId = Async.executionAsyncId();
if (!store[asyncId]) {
store[asyncId] = { uuid: autoInc++ };
console.log('ASYNC Created', store[asyncId]);
} else {
console.log('ASYNC Reuse', store[asyncId]);
}
if (!promise) {
promise = Promise.resolve();
}
if (index < 1) {
setTimeout(() => run(index+1), 0); // -> Version A
// promise.then(() => run(index+1)); // -> Version B
}
}
setTimeout(() => run(0), 0);
setTimeout(() => run(0), 0);
If i try 'Version A' (with setTimout) i've this output:
ASYNC Created { uuid: 0 }
ASYNC Created { uuid: 1 }
ASYNC Reuse { uuid: 0 }
ASYNC Reuse { uuid: 1 }
But if i try 'Version B' (with promises) i've this output:
ASYNC Created { uuid: 0 }
ASYNC Reuse { uuid: 0 }
ASYNC Created { uuid: 1 }
ASYNC Reuse { uuid: 0 }
The second execution context is attached to the first because the "then" is rattached on a promise of the first context. But it's very problematic: I cannot use it like a "ThreadLocal" in java. Do you have a solution? I can create a second promise to resolve the problem but it's not an acceptable solution for me.
Regards.
Thanks to @Robert Kawecki for library cls-hooked. I don't understand why but this library works better than async_hook method:
const CLS = require('cls-hooked');
const namespace = CLS.createNamespace('try-it');
let autoInc = 0;
let promise;
let allStores = [];
function run(index) {
namespace.run(() => {
const currentValue = namespace.get('id-context');
if (currentValue === undefined) {
namespace.set('id-context', autoInc++)
console.log('namespace Created', namespace.get('id-context'));
} else {
console.log('namespace Reuse', namespace.get('id-context'));
}
if (!promise) {
promise = Promise.resolve();
}
if (index < 1) {
// setTimeout(() => run(index + 1), 0); // -> Version A
// promise.then(() => run(index + 1)); // -> Version B
setTimeout(() => {
promise.then(() => run(index + 1));
}, 10) // -> Version C
}
});
}
setTimeout(() => run(0), 0);
setTimeout(() => run(0), 0);
Versions A and C says
namespace Created 0
namespace Created 1
namespace Reuse 0
namespace Reuse 1
And version B says:
namespace Created 0
namespace Reuse 0
namespace Created 1
namespace Reuse 1
So i think that with this library Promises are rewrited to resolve the problem, but thanks for the solution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.