Important Note:
The examples provided below are purely for demonstration purposes and should not be used in a real application. Some of them may even fall under The Deferred anti-pattern. They are meant to showcase how certain functions work.
To address the question at hand, let's conduct some experiments to explore it further.
Given the following callback functions:
function okHandler(value) {
console.log(value + ' has been called.');
return value;
}
function doneHandler(values) {
console.log('Done! : ' + JSON.stringify(values));
}
function delayed(value, delay) {
var deferred = $q.defer();
$timeout(function () {
deferred.resolve(value);
}, delay);
return deferred.promise;
}
Parallel Execution:
$q.all({
a: $q.when('a').then(okHandler),
b: $q.when('b').then(okHandler),
c: $q.when('c').then(okHandler),
}).then(doneHandler);
Result:
a has been called.
b has been called.
c has been called.
Done! : {"a":"a","b":"b","c":"c"}
Parallel Execution with Delay Simulation:
$q.all({
a: delayed('da', 200).then(okHandler),
b: delayed('db', 100).then(okHandler),
c: delayed('dc', 300).then(okHandler),
}).then(doneHandler);
Result:
db has been called.
da has been called.
dc has been called.
Done! : {"b":"db","a":"da","c":"dc"}
Sequential Execution:
delayed('sa', 400).then(okHandler).then(function () {
delayed('sb', 100).then(okHandler).then(function () {
delayed('sc', 10).then(okHandler).then(doneHandler);
})
});
Result:
sa has been called.
sb has been called.
sc has been called.
Done! : "sc"
Alternative Sequential Style:
delayed('ssa', 600)
.then(okHandler)
.then(delayed.bind(null, 'ssb', 100))
.then(okHandler)
.then(delayed.bind(null, 'ssc', 10))
.then(okHandler)
.then(doneHandler);
Result:
ssa has been called.
ssb has been called.
ssc has been called.
Done! : "ssc"
Example Plunker: http://plnkr.co/edit/dNZ8koAS4G6fNmahfmj6?p=preview
Now, let's proceed to address your specific queries.
Q: Is the execution order always guaranteed to be func1
, func2
, func3
, func4
?
A: No, only func4
is guaranteed to be executed last. The sequence of func1
, func2
, and func3
can vary.
Q: Does $q.then(callbacks).then
always ensure that callbacks are fired before moving to the next then block?
A: Yes!