ノードasync_hooksを使用して非同期スタックを介してコンテキストをトラッキングしようとしています。async_hooksでコンテキストを追跡する
service.js:それはほとんどの場合のために働く、しかし私は私が解決する方法を考えることができないこのユースケースを発見した
const asyncHooks = require('async_hooks');
class Service {
constructor() {
this.store = {};
this.hooks = asyncHooks.createHook({
init: (asyncId, type, triggerAsyncId) => {
if (this.store[triggerAsyncId]) {
this.store[asyncId] = this.store[triggerAsyncId];
}
},
destroy: (asyncId) => {
delete this.store[asyncId];
},
});
this.enable();
}
async run(fn) {
this.store[asyncHooks.executionAsyncId()] = {};
await fn();
}
set(key, value) {
this.store[asyncHooks.executionAsyncId()][key] = value;
}
get(key) {
const state = this.store[asyncHooks.executionAsyncId()];
if (state) {
return state[key];
} else {
return null;
}
}
enable() {
this.hooks.enable();
}
disable() {
this.hooks.disable();
}
}
module.exports = Service;
service.spec.jsを
const assert = require('assert');
const Service = require('./service');
describe('Service',() => {
let service;
afterEach(() => {
service.disable();
});
it('can handle promises created out of the execution stack', async() => {
service = new Service();
const p = Promise.resolve();
await service.run(async() => {
service.set('foo');
await p.then(() => {
assert.strictEqual('foo', service.get());
});
});
});
});
next
を呼び出すときに作成されたpromiseのtriggerAsyncIdがPromise.resolve()呼び出しのexecutionAsyncIdであるため、このテストケースは失敗します。現在の非同期スタックの外側で作成されたもので、別のコンテキストです。私はそれが作成されたコンテキストとnext
機能の非同期コンテキストと結婚する方法を参照することはできません。
https://github.com/domarmstrong/async_hook_then_example
https://github.com/nodejs/help/issues/1036ノードヘルプrepoに問題を作成しました。 – DomA