I'm still trying to get my head around all this and I'm obviously missing some fundamental concepts.
In my code I have a scenario whereby I want to call several functions in a row and when they've all completed, wrap it up with a finishing routine where subtotals are calculated and a pie chart is updated.
Although the functions I call themselves aren't asynchronous, they do contain ajax calls which are, hence why I want to wait for all of them to finish before I calculate totals and update the chart.
So I tried doing:
var fnArray= [];
fnArray.push(genericCalc("use_", true, false, false));
fnArray.push(doArticleImpacts(false));
fnArray.push(genericProjectCalc("tpD2C_", false, false));
fnArray.push(genericCalc("eol_", true, false, false));
fnArray.push(calcPackaging(false));
var calcPromise = Q.all(fnArray);
return calcPromise
.then(calcsDone)
.fail(calcsFailed);
function calcsDone() {
calcTotals();
setChart(selectedRow());
}
function calcsFailed() {
logger.logError("Failure in calculations", "", null, true);
}
...but using the above code and using the script debugger with a stop on the "return calcPromise" line, the fnArray is set to "0:undefined, 1:undefined, 2:Object, 3:undefined, 4:Promise" even before the promise is activated.
I understand that this is obviously something to do with my functions, but I don't really understand what I need to do differently. The functions all vary slightly, but are fundamentally something like:
var genericCalc = function (calcPrefix) {
var res_Array = ko.observable(); //holds returned results
prjArticleArray.forEach(function (thisArticle) {
var calcPromise = calcEOL(res_Array, thisArticle); //another function containing async ajax call
return calcPromise
.then(calcsDone)
.fail(calcsFailed);
function calcsDone() {
//do calculation subtotals here and set a knockout observable value
}
function calcsFailed() {
logger.logError("Failure in " + calcPrefix + "calculation", "", null, true);
}
});
};
What is it that makes some of the functions "undefined", some "object" and some "promise" in my array that I want to use for Q.all? Do I have to have "Q.resolve" in the "calcsDone" part of the functions I'm calling?
I've seen other questions/answers on stackoverflow along similar lines, but they seem to always be calls directly to async calls and my fist level functions I'm stacking up in the promise aren't... should I not be using this structure for non-async calls or just add "setTimeout" to my function calls to make them async?