bardman bardman - 1 month ago 8
Javascript Question

jQuery: queue up a function after click events

I have a problem with queueing up events in jquery. I have an elevator project that allows the user to click on buttons, and then lights go on and then numbers change. That works fine, except when they punch a number again before it reaches the floor picked the first time. I want it to get to the floor first picked before it goes to the second clicked floor (or third, or fourth, etc.). I've done some stuff with .promise, when done, etc. and none of it seems to work.

I am using .click which appears to be the issue, because it fires the function regardless of where it is currently. Trouble is that I can't seem to find any alternative and it needs to finish current operation first before moving on to any other floors.

I hope I explained this well. If not please let me know. Perhaps there is another way entirely of doing it. Still learning this front end/jQuery stuff.

$( ".button" ).click(function(event) {
// doing stuff here....
$( runMainscript() ).promise().done(function() {
runMainscript(buttonclicked, floorQ);
});

});

function runMainscript(buttonclicked,floorQ) {
//doing stuff here
}


BTW, here is a timer for 2 seconds on each floor.

JSfiddle: http://jsfiddle.net/ak25Lxab/1/

See how if you click on two buttons quickly, it jumps around?

Answer

The deferred object works slightly differently. You should explicitly declare a deferred variable like this:

var dfd = new $.Deferred();

And when you want to fire done callback, you should call:

dfd.resolve();

So your queueing part of the script now looks like this:

$.when(dfd.promise()).done(function() {
    dfd = new $.Deferred();
    var onfloor = $("#onfloor").text();
    runMainscript(buttonclicked, floorQ, onfloor);
});

And inside runMainscript you resolve this dfd deferred when elevator arrived to the floor. See demo. Now, all floors are in the queue using deferred object.

I'm not an expert in deferreds, so maybe you can optimise this script further.