跟踪方面具有async
我试图通过跟踪使用节点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());
});
});
});
});
因为承诺的triggerAsyncId创建时调用next
是Promise.resolve()调用的executionAsyncId这个测试用例将会失败。这是当前的异步栈之外创建并且是一个独立的上下文。我看不到任何方式与结婚其创建的背景下next
功能异步上下文。
我写了一个非常类似的包叫做node-request-context与blog post来解释它。
您还没有定义任何foo
价值,没有任何按键调用service.get()
当你不要求任何价值。但我想这是一个小的失误,当你写的问题。
你被点名的主要问题是Promise.resolve
的位置。我同意,没有办法,使其工作。这正是你所创建的run
功能的原因,所以你会赶上executionAsyncId
并用它追踪你的代码。否则,你可以不跟踪任何上下文。
您的代码只是为了测试,但如果你真的需要,你可以用箭头功能作弊:
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', 'bar');
await p().then(() => {
assert.strictEqual('bar', service.get('foo'));
});
});
});
跟踪方面具有async
我试图通过跟踪使用节点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());
});
});
});
});
因为承诺的triggerAsyncId创建时调用next
是Promise.resolve()调用的executionAsyncId这个测试用例将会失败。这是当前的异步栈之外创建并且是一个独立的上下文。我看不到任何方式与结婚其创建的背景下next
功能异步上下文。
我写了一个非常类似的包叫做node-request-context与blog post来解释它。
您还没有定义任何foo
价值,没有任何按键调用service.get()
当你不要求任何价值。但我想这是一个小的失误,当你写的问题。
你被点名的主要问题是Promise.resolve
的位置。我同意,没有办法,使其工作。这正是你所创建的run
功能的原因,所以你会赶上executionAsyncId
并用它追踪你的代码。否则,你可以不跟踪任何上下文。
您的代码只是为了测试,但如果你真的需要,你可以用箭头功能作弊:
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', 'bar');
await p().then(() => {
assert.strictEqual('bar', service.get('foo'));
});
});
});