Awaiting inside a setInterval prevents setTimeout from being called
See original GitHub issueš Bug Report
I am trying to mock a setTimeout inside of a setInterval with Jest, but am seeing confusing behavior with async/await and I do not know whether it is a bug, or if I am doing something wrong.
Awaiting inside the async function passed to setInterval causes setTimeout to never run. If I remove the await in the function below, the setTimeout is successfully set.
To Reproduce
See updated Reproduction Case in my Below Comment
// With await, setTimeout is never called
let interval;
async function check() {
await Promise.resolve(true); //does not execute the setTimeout below
setTimeout(() => {
console.log('Hello World');
clearInterval(interval);
}, 1000);
}
const testFunction = async () => {
interval = setInterval(check, 1000);
};
describe('Timers', () => {
beforeEach(() => {
jest.useFakeTimers();
});
it('should set a timeout that prints Hello World', async () => {
await testFunction();
jest.advanceTimersByTime(100000);
});
});
// Removing the await, the setTimeout is executed
let interval;
async function check() {
Promise.resolve(true);
setTimeout(() => {
console.log('Hello World');
clearInterval(interval);
}, 1000);
}
const testFunction = async () => {
interval = setInterval(check, 1000);
};
describe('Timers', () => {
beforeEach(() => {
jest.useFakeTimers();
});
it('should set a timeout that prints Hello World', async () => {
await testFunction();
jest.advanceTimersByTime(100000);
});
});
Expected behavior
setTimeout to run after a promise resolves.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:6
Top Results From Across the Web
Jest: awaiting inside a setInterval prevents setTimeout from ...
I am trying to mock a setTimeout inside of a setInterval with Jest, but am seeing confusing behavior and I do not know...
Read more >Scheduling: setTimeout and setInterval
When a function is passed in setInterval/setTimeout , an internal reference is created to it and saved in the scheduler. It prevents theĀ ......
Read more >Asynchronous JavaScript 1 of 3: setTimeout, setInterval ...
This is the first episode in a set of 3 where we'll talk about how JavaScript runs asynchronously. In this episode, we'll use...
Read more >setTimeout vs setInterval | Top 4 Differences You Should Know
The setTimeout is function used as settimeout(). It is used for executing a defined block of code after a specific time period, and...
Read more >Using setTimeout() and other timer APIs in Node.js
setTimeout () returns a Timeout object, which may be used to terminate the timeout using the clear method known as clearTimeout() . One...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
@SimenB ran into this. Removed
jest.useFakeTimers
, issue was resolved. My workaround was:I have this issue as well.
Given a function that creates a setInterval inside. setIntervalās callback is an async function, which awaits for something and then invokes another function (Iām testing the result of this invoked function).
In my tests Iām using
runOnlyPendingTimers
oradvanceTimersByTime
but by the time I do theexpect
await inside the function I test is triggered afterwards, so my assert fails.Iāve tried adding
await Promise.resolve()
after advancing my timers but still nothing changes.So, I donāt think this is a bug, the timers are advanced but thereās no way to wait for that await š¦
Later edit:
If i stack
This seems to make it work but I donāt really want to do that.
Later later edit:
I made it work somehow, hereās an example:
This seems to make it work