I have a set of callbacks that may run on different durations before I close my web app. I also have a timeout where if it reaches past the timeout duration, I also close the application. The reason for this is to prevent the callbacks from blocking in closing the web app if it passes timeout duration.
Here is my current solution:
public close() {
const callbacks = this.onBeforeCloseCallbacks.map((cb) => new Promise(res => res(cb())));
const timeout = new Promise((res) => setTimeout(res, TIMEOUT_DURATION));
await Promise.race([Promise.all(callbacks), timeout]).then((value) => {
// Currently returns Promise.all(callbacks) right away
console.log(value)
});
await this.pluginEngine.close();
}
}
These are my tests
it('Should still close the plugin when timing out', async () => {
// Arrange
const cleanupMock = jest.fn();
const cb1 = jest.fn().mockReturnValue(async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb1')), 3000)));
const cleanupMock2 = jest.fn();
const cb2 = jest.fn().mockReturnValue(async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb2')), 11000)));
const placementCloseService = new PlacementCloseService(integrationMock, pluginInterface);
// Act
// onBeforeClose is registering callbacks that needs to be run before close
placementCloseService.onBeforeClose(cb1);
placementCloseService.onBeforeClose(cb2);
await placementCloseService.close();
// Assert
expect(cleanupMock).toBeCalled();
expect(cleanupMock2).not.toBeCalled();
expect(pluginInterface.context.close).toBeCalled();
});
My current solution is returning Promise.all(callbacks)
even if it hasn't called expected callbacks to run yet. What I expect to happen is that it passes through my timeout
instead since it has a timer of 4000 and the last closeCallback has a timer of 5000.
What am I doing wrong?
CodePudding user response:
Your closeCallbacks
are not async, You need them to return a promise
.
const closeCallbacks = [
// for sample purposes. i assigned timeouts to mock that it takes longer to run these callbacks then my timeout duration
async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb1')), 3000)),
async () => new Promise(resolve => setTimeout(() => resolve(console.log('cb2')), 5000)),
];
CodePudding user response:
This creates a parameter named async
not an async function
(async) => {}
Your timeout
function never calls res
parameter
const wait = (cb, time) => new Promise(r => { cb(); r() }, time)
const closeCallbacks = [
() => wait(() => console.log('cb1'), 3000),
() => wait(() => console.log('cb2'), 5000)
];
const timeout = new Promise((res) => setTimeout(() => console.log('timeout'); res(), 4000));