【发布时间】:2021-10-21 07:42:11
【问题描述】:
我想知道以前是否有人遇到过这个问题。
在我有一个看起来像这样的 EventHandler 之前:
export interface EventHandler {
name: string;
canHandleEvent(event: EventEntity): boolean;
handleEvent(event: EventEntity): Promise<void>;
}
我的过滤器功能可以正常工作,我的测试也通过了 - 我使用以下方法过滤事件:
messages.forEach(message => {
const event: EventEntity = JSON.parse(message.Body);
this.handlers
.filter(handler => handler.canHandleEvent(event)) // WORKED WELL
.forEach(handler => {
// LOGIC
});
目前,我们必须将 canHandleEvent 更改为布尔值或 Promise。因为我们有一些承诺要解决并确定事件是否可以处理。
export interface EventHandler {
// ...
canHandleEvent(event: EventEntity): boolean | Promise<boolean>;
}
所以,为了解决这个问题,我使用了Promise.resolve 和Promise.all。运气不好:
messages.forEach(async message => {
const event: EventEntity = JSON.parse(message.Body);
const handlersResolved = await Promise.all(this.handlers);
handlersResolved
.filter(handler => handler.canHandleEvent(event))
.forEach(handler => {
现在,我对 Promise canHandleEvent 的测试通过了,但对于通过的事件 boolean,它们却失败了。它们看起来像这样:
class HandlerB implements EventHandler {
name = HandlerB.name;
numRuns = 0;
canHandleEvent(event: EventEntity): boolean {
console.log('event', event)
return event.eventType === EventType.ONE_EVENT || event.eventType === EventType.SECOND_EVENT;
}
async handleEvent(event: EventEntity): Promise<void> {
return new Promise(resolve => {
setTimeout(() => {
this.numRuns += 1;
resolve();
}, 25);
});
}
}
我现在失败和之前通过的测试是:
it('Should process handlers that match, including canHandleEvent that returns Promise<boolean> TRUE', async () => {
setHandlers([handlerA, handlerB, handlerC]);
const event = await createEvent(EventType.SECOND_EVENT);
await sleep(1000);
expect(handlerA.numRuns, 'handleA').to.eql(0);
expect(handlerB.numRuns, 'handleB').to.eql(1);
expect(handlerC.numRuns, 'handleC').to.eql(1); // handlerC is Promise<boolean>, it works fine
expect(errorHandler.numRuns).to.eql(0);
handlerC.numRuns = 0;
});
it('Should allow handlers to pass even if one has an error', async () => {
setHandlers([handlerA, handlerB, errorHandler]);
const event = await createEvent(EventType.USER_REGISTRATION_STATUS);
await sleep(1000);
expect(handlerA.numRuns, 'handlerA').to.eql(1);
expect(handlerB.numRuns, 'handlerB').to.eql(1);
expect(errorHandler.numRuns, 'errorHandler').to.eql(1);
});
关于如何解决这个问题的任何想法?我尝试在.filter 之前确定是promise 还是boolean,但仍然没有运气:
this.handlers
.filter(async handler => {
if(typeof handler.canHandleEvent(event).then == 'function') {
const result = await Promise.resolve(handler.canHandleEvent(event))
console.log('IS PROMISE!!', result);
return result
}
console.log('IT IS NOT PROMISE', handler.canHandleEvent(event))
return handler.canHandleEvent(event)
})
【问题讨论】:
标签: javascript typescript promise