async await with setInterval

﹥>﹥吖頭↗ 提交于 2020-04-06 04:51:10

问题


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?


回答1:


You have a few problems:

  1. Promises may only ever resolve once, setInterval() is meant to call the callback multiple times, Promises do not support this case well.
  2. Neither setInterval(), nor the more appropriate setTimeout() return Promises, therefore, awaiting 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();



回答2:


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)



回答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));
}



回答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)


来源:https://stackoverflow.com/questions/52184291/async-await-with-setinterval

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!