async await with setInterval
function first(){
console.log('first')
}
function second(){
console.log('second')
}
let interval = async ()=>{
await setInterval(first,2000)
await setInterval(second,2000)
}
interval();
Imagine that I have this code above.
When I run it, first()
and second()
will be called at the same time; how do I call second()
after first)()
returns some data, for example, if first()
is done, only then call second()
?
Because first()
in my code will be working with a big amount of data and if this 2 functions will be calling at the same time, it will be hard for the server.
How do I call second()
each time when first()
will return some data?
Solution 1:
As mentioned above setInterval
does not play well with promises if you do not stop it. In case you clear the interval you can use it like:
async function waitUntil(condition) {
return await new Promise(resolve => {
const interval = setInterval(() => {
if (condition) {
resolve('foo');
clearInterval(interval);
};
}, 1000);
});
}
Later you can use it like
const bar = waitUntil(someConditionHere)
Solution 2:
You have a few problems:
- Promises may only ever resolve once,
setInterval()
is meant to call the callback multiple times, Promises do not support this case well. - Neither
setInterval()
, nor the more appropriatesetTimeout()
return Promises, therefore,await
ing on them is pointless in this context.
You're looking for a function that returns a Promise which resolves after some times (using setTimeout()
, probably, not setInterval()
).
Luckily, creating such a function is rather trivial:
async function delay(ms) {
// return await for better async stack trace support in case of errors.
return await new Promise(resolve => setTimeout(resolve, ms));
}
With this new delay
function, you can implement your desired flow:
function first(){
console.log('first')
}
function second(){
console.log('second')
}
let run = async ()=>{
await delay(2000);
first();
await delay(2000)
second();
}
run();
Solution 3:
setInterval
doesn't play well with promises because it triggers a callback multiple times, while promise resolves once.
It seems that it's setTimeout
that fits the case. It should be promisified in order to be used with async..await
:
async () => {
await new Promise(resolve => setTimeout(() => resolve(first()), 2000));
await new Promise(resolve => setTimeout(() => resolve(second()), 2000));
}
Solution 4:
await expression causes async to pause until a Promise is settled
so you can directly get the promise's result without await
for me, I want to initiate Http request every 1s
let intervalid
async function testFunction() {
intervalid = setInterval(() => {
// I use axios like: axios.get('/user?ID=12345').then
new Promise(function(resolve, reject){
resolve('something')
}).then(res => {
if (condition) {
// do something
} else {
clearInterval(intervalid)
}
})
}, 1000)
}
// you can use this function like
testFunction()
// or stop the setInterval in any place by
clearInterval(intervalid)