I'm trying to create a function queue with several functions in it. After the creation i want to execute each function in it's turn. But these function have delayed instructions inside of them, so i want to wait for each of the functions to complete its execution before the continuing.
My attempts:
var funqueue = [];
funqueue.push( function() {fun1() });
funqueue.push( function() {fun2() });
funqueue.push( function() {fun3() });
executeFunctionQueue(funqueue);
Where the execute function is:
function executeFunctionQueue(funqueue){
var fun1=funqueue.pop;
$.when(fun1()).then(executeFunctionQueue(funqueue));
}
But this does not work. How should i do it?
Try utilizing .queue()
, .promise()
; see also Change easing functions on animations in jQuery queue
function fun1() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(1)
}, 1500)
}).promise().then(msg)
}
function fun2() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(2)
}, 1500)
}).promise().then(msg)
}
function fun3() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(3)
}, 1500)
}).promise().then(msg)
}
var funqueue = [];
funqueue.push(function() {
return fun1()
});
funqueue.push(function() {
return fun2()
});
funqueue.push(function() {
return fun3()
});
function msg(data) {
if (data === "complete") console.log(data)
else $("body").append(data + "<br>")
}
function executeFunctionQueue(funqueue) {
var deferred = funqueue.pop();
return deferred().then(function() {
// set `this` within `$.queue()` , `.then()` to empty object `{}`,
// or other object
return $({}).queue("fun", $.map(funqueue, function(fn) {
return function(next) {
// return `next` function in `"fun"` queue
return fn().then(next)
}
})).dequeue("fun").promise("fun")
.then(function() {
// return "complete" string when `fun` queue empty
return "complete"
})
});
}
executeFunctionQueue(funqueue)
.then(msg);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
Alternatively , using $.when()
function executeFunctionQueue(funqueue) {
return $.when(!!funqueue[funqueue.length - 1]
? funqueue.pop().call().then(function() {
return executeFunctionQueue(funqueue)})
: "complete")
}
executeFunctionQueue(funqueue)
.then(function(complete) {
console.log(complete)
});
function fun1() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(1)
}, 1500)
}).promise().then(msg)
}
function fun2() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(2)
}, 1500)
}).promise().then(msg)
}
function fun3() {
return $.Deferred(function(dfd) {
setTimeout(function() {
dfd.resolve(3)
}, 1500)
}).promise().then(msg)
}
var funqueue = [];
funqueue.push(function() {
return fun1()
});
funqueue.push(function() {
return fun2()
});
funqueue.push(function() {
return fun3()
});
function msg(data) {
if (data === "complete") console.log(data)
else $("body").append(data + "<br>")
}
function executeFunctionQueue(funqueue) {
return $.when(!!funqueue[funqueue.length - 1]
? funqueue.pop().call().then(function() {
return executeFunctionQueue(funqueue)})
: "complete")
}
executeFunctionQueue(funqueue)
.then(msg);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
If you have functions that return Promise
s, this can be done very simply with a function like sequence
:
// sequence :: [(undefined -> Promise<undefined>)] -> Promise<undefined>
function sequence(fns) {
var fn = fns.shift();
return fn ? fn().then(sequence.bind(null, fns)) : Promise.resolve(undefined);
}
sequence
assumes that your asynchronous/Promise
-returning functions do not take any inputs and do not produce any outputs (that they are merely being called for side-effects.)
An example usage of the sequence
function is:
sequence([f1, f2, f3]);
function f1() {
return new Promise(function (res) {
setTimeout(function () {
console.log('f1');
res();
}, 100);
});
}
function f2() {
return new Promise(function (res) {
setTimeout(function () {
console.log('f2');
res();
}, 1100);
});
}
function f3() {
return new Promise(function (res) {
setTimeout(function () {
console.log('f3');
res();
}, 10);
});
}
This will log out 'f1', 'f2', and 'f3' in order with the varying, specified time delays in between.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With