mirror of
https://github.com/Mintplex-Labs/nut.js.git
synced 2026-07-19 14:06:17 -04:00
Merge pull request #177 from nut-tree/fix/174/waitFor-does-not-properly-cancel
(#174) Cancel interval timer creation
This commit is contained in:
@@ -118,4 +118,28 @@ describe("poll-action", () => {
|
||||
expect(action).toBeCalledTimes(1);
|
||||
expect((end - start)).toBeLessThan(updateInterval);
|
||||
});
|
||||
|
||||
it("should fail if action does not resolve within timeout", async () => {
|
||||
// GIVEN
|
||||
const updateInterval = 100;
|
||||
const maxDuration = 200;
|
||||
const action = jest.fn(() => {
|
||||
return new Promise((_, reject) => {
|
||||
setTimeout(() => reject(), 300);
|
||||
})
|
||||
});
|
||||
|
||||
// WHEN
|
||||
const start = Date.now();
|
||||
try {
|
||||
await timeout(updateInterval, maxDuration, action);
|
||||
} catch (e) {
|
||||
expect(e).toEqual(`Action timed out after ${maxDuration} ms`);
|
||||
}
|
||||
const end = Date.now();
|
||||
|
||||
// THEN
|
||||
expect(action).toBeCalledTimes(1);
|
||||
expect((end - start)).toBeGreaterThanOrEqual(maxDuration);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,41 +1,45 @@
|
||||
export function timeout<R>(updateIntervalMs: number, maxDurationMs: number, action: (...params: any) => Promise<R>): Promise<R> {
|
||||
return new Promise<R>((resolve, reject) => {
|
||||
let interval: NodeJS.Timeout;
|
||||
const maxTimeout = setTimeout(
|
||||
() => {
|
||||
clearTimeout(maxTimeout);
|
||||
if (interval) {
|
||||
clearTimeout(interval);
|
||||
}
|
||||
reject(`Action timed out after ${maxDurationMs} ms`);
|
||||
},
|
||||
maxDurationMs
|
||||
);
|
||||
const startInterval = () => {
|
||||
interval = setTimeout(function intervalFunc() {
|
||||
action().then((result) => {
|
||||
if (!result) {
|
||||
interval = setTimeout(intervalFunc, updateIntervalMs);
|
||||
} else {
|
||||
clearTimeout(maxTimeout);
|
||||
clearTimeout(interval);
|
||||
resolve(result);
|
||||
}
|
||||
}).catch(() => {
|
||||
interval = setTimeout(intervalFunc, updateIntervalMs);
|
||||
});
|
||||
}, updateIntervalMs);
|
||||
};
|
||||
let timerCleaned = false
|
||||
|
||||
action().then((result) => {
|
||||
function executeInterval() {
|
||||
action().then(validateResult).catch(handleRejection);
|
||||
}
|
||||
|
||||
function validateResult(result: R){
|
||||
if (!result) {
|
||||
startInterval();
|
||||
interval = setTimeout(executeInterval, updateIntervalMs);
|
||||
} else {
|
||||
clearTimeout(maxTimeout);
|
||||
cleanupTimer();
|
||||
resolve(result);
|
||||
}
|
||||
}).catch(() => {
|
||||
startInterval();
|
||||
});
|
||||
}
|
||||
|
||||
function handleRejection() {
|
||||
if(!timerCleaned){
|
||||
interval = setTimeout(executeInterval, updateIntervalMs);
|
||||
}
|
||||
}
|
||||
|
||||
function cleanupTimer(){
|
||||
timerCleaned = true
|
||||
if(maxTimeout){
|
||||
clearTimeout(maxTimeout);
|
||||
}
|
||||
if(interval){
|
||||
clearTimeout(interval);
|
||||
}
|
||||
}
|
||||
|
||||
const maxTimeout = setTimeout(
|
||||
() => {
|
||||
cleanupTimer();
|
||||
reject(`Action timed out after ${maxDurationMs} ms`);
|
||||
},
|
||||
maxDurationMs
|
||||
);
|
||||
|
||||
executeInterval()
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user