在JavaScript中的承诺/链接功能混淆位 [英] A bit confused with promises/chained functions in javascript

查看:268
本文介绍了在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 current genericCalc function does not even contain a return statement (only the forEach callback function inside it does), so it does return undefined.

If you need to wait for the result of each article, use Q.all like you have already done with fnArray (which is a promiseArray actually). In genericCalc 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 your calcsDone function, and it will resolve the result promise with that value.

这篇关于在JavaScript中的承诺/链接功能混淆位的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆