javascript - 与 javascript 中的 promise /链式函数有点混淆

标签 javascript jquery ajax asynchronous promise

我仍在努力理解这一切,但我显然缺少一些基本概念。

在我的代码中,我有一个场景,我想连续调用多个函数,当它们全部完成时,用一个完成例程来结束它,在该例程中计算小计并更新饼图。

虽然我调用的函数本身不是异步的,但它们确实包含 ajax 调用,因此我想等待所有函数完成后再计算总数并更新图表。

所以我尝试这样做:

    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);
    }

...但是使用上面的代码并使用脚本调试器并在“return calcPromise”行上停止,fnArray 设置为“0:未定义,1:未定义,2:对象,3:未定义,4 :Promise”甚至在 promise 被激活之前。

我知道这显然与我的功能有关,但我真的不明白我需要做什么不同的事情。这些功能都略有不同,但基本上都是这样的:

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);
        }

    });
};

是什么使得我想要用于 Q.all 的数组中的某些函数“未定义”、某些“对象”和某些“ promise ”?我调用的函数的“calcsDone”部分中是否必须有“Q.resolve”?

我在 stackoverflow 上看到了类似的其他问题/答案,但它们似乎总是直接调用异步调用,而我在 promise 中堆积的第一级函数不是......我不应该吗?是否将此结构用于非异步调用,或者只是将“setTimeout”添加到我的函数调用中以使其异步?

最佳答案

I understand that this is obviously something to do with my functions, but I don't really understand what I need to do differently

您需要从他们那里返回 promise 。您当前的 genericCalc 函数甚至不包含 return 语句(只有其中的 forEach 回调函数包含),因此它确实返回 未定义

如果您需要等待每篇文章的结果,请使用 Q.all 就像您已经使用 fnArray (这是一个 promiseArray实际上)。在 genericCalc 中,它应该如下所示:

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

这是一个坏主意。您不应该使用有时设置的全局变量,也不应该使用仅用于传播更改的 promise ,但 promise 应该代表这些值。这会带来更好的函数式编程风格。

因此,不要设置全局变量,而是从 calcsDone 函数返回结果,它将解决 result promise 值。

关于javascript - 与 javascript 中的 promise /链式函数有点混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22069689/

相关文章:

javascript - 过滤 HTML 表格,结果应位于 HTML 表格中

javascript - 防止未经授权访问 JavaScript 文件

javascript - 关于将 javascript 事件与 innerHTML DOM 元素绑定(bind)的问题

c# - jquery new Date() 在本地工作但不在线

javascript - 如何制作一个在最后一张图像处停止并带有重播按钮的图像 slider

javascript - 获取 data-* 设置为特定字符串的跨度的类名

javascript - 由于 PHP 重定向,AJAX 请求未完成

javascript - 如何仅在选择两个下拉菜单时触发事件?

javascript - 更改 parent 背景颜色的 div 颜色

javascript - jqGrid EditRow ErroFunc 回调用法