Websirnik
Websirnik

Reputation: 1412

How to dynamically add functions to the queue?

I have render(value) function that I'm calling multiple times with different parameters. I need to chain calls to this function, so that it starts execution only when previous call has finished.

The function I need to chain returns a promise:

function render(value){
   var deferred = $q.defer();

   /* Some logic here */

   return deferred.promise;
}

What should I place here?

function onClick(value){
   /*
       Add render(value) to the queue. And start execution if queue is empty
   */
}

Upvotes: 1

Views: 182

Answers (3)

Zubair Ahmd
Zubair Ahmd

Reputation: 308

People searching for vanila javascript solution for queing function and run can do it as following

//Create function to return a promise
const waitForMe = (message) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(message);
    }, 2000);
  });
};

//define promise que
let queue = Promise.resolve();
//create function to que calls to waitFroMe from callers
const QueFunction = (message) => {
  queue = queue.then(async () => {
    console.log(await waitForMe(message));
  });
};

//call QuetFunction and watch each return promise after 2000 ms (2sec)
QueFunction("Promise 1");
QueFunction("Promise 2");

//or call from button click each click will be qued and executed
const btn = document.getElementById("btn_run");
btn.addEventListener("click", () => {
  QueFunction("Call from button click");
});

Upvotes: 0

Benjamin Gruenbaum
Benjamin Gruenbaum

Reputation: 276306

That's just then chaining -

Creating the queue:

var queue = $q.when(); 

Adding a function to run on the queue:

queue = queue.then(function(){ // need to reassign since promises are immutable.
    console.log("Added!");
});

So, in your example:

function onClick(value){
  queue = queue.then(function(){ return render(value); });
}

Upvotes: 1

Nikos Paraskevopoulos
Nikos Paraskevopoulos

Reputation: 40298

You may want to try something along the lines of:

var lastPromise;

function onClick(value) {
    var promise;

    if( lastPromise ) {
        promise = lastPromise.then(function() {
            return render(value);
        }).then(cleanup);
    }
    else {
        promise = render(value).then(cleanup);
    }

    lastPromise = promise;

    function cleanup() {
        if( promise === lastPromise ) {
            lastPromise = null;
        }
    }
}

The lastPromise keeps the last promise for chaining; this makes sure that each render() will run after the previous has finished. The internal promise is a notion of the "private" promise. If, when we are resolved, the private promise is the same as the last promise, then we clean it up. WARNING: untested!

Upvotes: 0

Related Questions