Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call function at fixed interval with ensuring previous function is completed

Tags:

I have a Promise based function which i want to call at fixed interval, Lets say at every 60 seconds. But i also want to make sure that function is called only if the previously called function is executed completely and i want to continue this for infinite time

function fun(){
    return new Promise((resolve,reject)=>{
        //Some database queries which may or may not complete in 60 seconds
        resolve("done")
    })
}

setInterval(()=>{
    fun().then(d=>{
        console.log(d)
    })
},60000)

Above code will not check for previously called function is completed or not. but i want to make sure that

like image 772
Krunal Sonparate Avatar asked Jan 03 '19 12:01

Krunal Sonparate


2 Answers

class AsyncQueue {
  constructor() {
    this.queue = null;
  }

  push(task) {
    // If we have task in query, append new at the end, if not execute immediately
    // Every task appended to existing queue will be executed immediately after previous one is finished
    return this.queue = this.queue ? this.queue.then(() => task()) : task();
  }
}

const task = (id) => () => new Promise((resolve) => {
  console.log('Task', id, 'started');
  // Random time betwen 500-1300ms
  const time = Math.round(Math.random() * 800 + 500);
  setTimeout(() => {
    console.log("Finished task '" + id + "' after " + time + "ms");
    resolve();
  }, time);
});
const queue = new AsyncQueue();
let id = 0;
// This will push new task to queue every 1s
setInterval(() => {
  console.log("Pushing new task", ++id);
  queue.push(task(id));
}, 1000);

Of course we can implement it without using class

let queue;
function push(task) {
  return queue = queue ? queue.then(() => task()) : task();
}
// or
const push = (task) => queue = queue ? queue.then(() => task()) : task();
like image 129
ponury-kostek Avatar answered Nov 14 '22 21:11

ponury-kostek


Instead of calling the function in setInterval call it with setTimeout after response is received.

function fun(){
    return new Promise((resolve,reject)=>{
        //Some database queries which may or may not complete in 60 seconds
        resolve("done")
    })
}
//Function to call promise function recursively
function functionCaller(fn){
fn()
.then((response)=>{
   console.log(response)
   setTimeout(() => functionCaller(fn), 6000)
})
}

functionCaller(fun)
like image 32
Ashish Avatar answered Nov 14 '22 21:11

Ashish