在JavaScript中的承诺/链接功能混淆位 [英] A bit confused with promises/chained functions in javascript
问题描述
我仍然在试图让我的头周围的这一切,我显然缺少一些基本概念。
在我的code我有一个场景,由此我想打电话给几个功能在一排,当他们都完成,其中,小计计算和饼图更新整理程序包起来。
虽然我自称为函数不是异步的,他们确实包含Ajax调用它们,所以我为什么要等他们都完成之前,我计算总计和更新图表。
所以我尝试这样做的:
VAR fnArray = [];
fnArray.push(genericCalc(USE_,真,假,假));
fnArray.push(doArticleImpacts(假));
fnArray.push(genericProjectCalc(tpD2C_,假的,假的));
fnArray.push(genericCalc(eol_,真,假,假));
fnArray.push(calcPackaging(假)); VAR calcPromise = Q.all(fnArray); 返回calcPromise
。然后(calcsDone)
.fail(calcsFailed); 功能calcsDone(){
calcTotals();
setChart(selectedRow());
} 功能calcsFailed(){
logger.logError(失败在计算中,,NULL,TRUE);
}
...但使用上述code和使用脚本调试器上的返回calcPromise行停止,该fnArray设置为0:未定义,1:未定义,2:对象,3:未定义,4:无极之前也承诺被激活
我明白,这是很明显的东西与我的功能,但我真的不明白我需要做的不同。这些功能都略有不同,但基本上是这样的:
VAR genericCalc =函数(计算值preFIX){
变种res_Array = ko.observable(); //保存返回的结果
prjArticleArray.forEach(功能(本条第一){ VAR calcPromise = calcEOL(res_Array,本条第一); //包含异步Ajax调用另一个函数 返回calcPromise
。然后(calcsDone)
.fail(calcsFailed); 功能calcsDone(){
//做计算分类汇总这里设置了淘汰赛观察到的值
} 功能calcsFailed(){
logger.logError(失败的+钙preFIX +计算,,NULL,TRUE);
} });
};
这是什么使某些功能不确定,有的对象,并在我的数组,我想使用一些Q.all承诺?我必须在我打电话的功能的calcsDone部分有Q.resolve?
我已经看到了与之相似的计算器其他问题/答案,但他们似乎总是直接向异步调用电话,我的拳头级的功能,我堆叠起来的承诺都没有...我不应该使用这种结构的非异步调用,或只加的setTimeout我的函数调用,使它们异步?
我明白,这是很明显的东西与我的功能,但我真的不明白我需要做不同的
块引用>您需要
收益
从他们的承诺。您当前的genericCalc
功能甚至不包含收益
语句(仅的forEach
回调函数内它),因此它不会返回未定义
。如果您需要等待每篇文章的结果,使用
Q.all
像你已经断绝了fnArray
(这是promiseArray
实际上)。在genericCalc
就应该是这样的:VAR genericCalc =函数(计算值preFIX){
返回Q.all(prjArticleArray.map(功能(本条第一){
VAR calcPromise = calcEOL(res_Array,本条第一); //包含异步Ajax调用另一个函数
VAR的结果= calcPromise
。然后(calcsDone)
.fail(calcsFailed);
返回结果;
...
});
};VAR res_Array = ko.observable(); //保存返回的结果
...
//做计算分类汇总这里设置了淘汰赛观察到的值
块引用>这是一个坏主意。你不应该使用那些somewhen设置全局变量和使用的承诺只是为了传播变化,但承诺应的再present 的这些值。这导致了一个更好的,功能性的编程风格。
因此,而不是设置一个全局变量,请
收益
从calcsDone
函数的结果,这将解决在结果
承诺与价值。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?
解决方案I understand that this is obviously something to do with my functions, but I don't really understand what I need to do differently
You need to
return
promises from them. Your currentgenericCalc
function does not even contain areturn
statement (only theforEach
callback function inside it does), so it does returnundefined
.If you need to wait for the result of each article, use
Q.all
like you have already done withfnArray
(which is apromiseArray
actually). IngenericCalc
it should look like this:var genericCalc = function (calcPrefix) { return Q.all(prjArticleArray.map(function (thisArticle) { var calcPromise = calcEOL(res_Array, thisArticle); //another function containing async ajax call var result = calcPromise .then(calcsDone) .fail(calcsFailed); return result; … }); };
var res_Array = ko.observable(); //holds returned results … //do calculation subtotals here and set a knockout observable value
That is a bad idea. You should not use global variables that are set somewhen and use promises just for propagating changes, but the promises should represent these values. This leads to a better, functional programming style.
So instead of setting a global variable, do
return
the result from yourcalcsDone
function, and it will resolve theresult
promise with that value.这篇关于在JavaScript中的承诺/链接功能混淆位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!