【问题标题】:How to make a function that contains a promise return a value instead of a promise?如何使包含承诺的函数返回值而不是承诺?
【发布时间】:2015-03-25 11:55:44
【问题描述】:

说,我有一个函数 F1,它将在许多其他函数中被调用。 F1 旨在返回将在 F2 中使用的值 VAL。需要一个承诺来检索有助于计算 VAL 的所需数据。将 F1 作为 Promise 会在 F2 中引起很多混乱,因为 F1 通常在 IF 语句和 FOR 循环中调用。让我来说明一下这个场景:

function F1(param1, param2) {
    var VAL = 0;

    promise(param1, param2).then(function(data) {
        for (var i = 0; i < data.length; i++) {
            // Do some calculation here
        }
    });

    return VAL;
}

function F2(x1, x2) {
    var myArray = [],
        someValue = 0;

    if ([conditional expression]) {
        someValue = F1(x1, x2);

        call_some_function();

        myArray.push({
          val: someValue,
          ...
        });
    }

    var x = someValue + y;

    myArray.push({
        id: x,
        ...
    });

    return myArray;
}

如何确保 F1 返回 VAL(整数)以便我可以将其用作同步函数?

提前感谢您的帮助。

编辑:

代码如下所示:

    function myFunc(x, y) {
        return init()
            .then(function() {
                return getData(x, y).then(function(data) {
                    if (data.length == 0) return [];

                    var id, name, 
                        firstPass = true,
                        headIn = 0, 
                        headOut = 0, 
                        currentHead = 0,
                        payWtIn = 0,
                        payWtOut = 0,
                        expectedAdg = 0,
                        weight = 0,
                        results = [];

                    for (var i = 0; i < data.length; i++) {
                        if (firstPass) {
                            id = data[i].id();
                            name = data[i].name();
                            headIn = data[i].headIn();
                            headOut = data[i].headOut();
                            expectedAdg = data[i].expectedAdg();
                            firstPass = false;
                        }

                        if (id != data[i].id()) {
                            buildFunc();
                            reset();
                        }

                        headIn += data[i].headIn();
                        headOut += data[i].headOut();
                        payWtIn += data[i].payWtIn();
                        payWtOut += data[i].payWtOut();
                    }

                    buildFunc();

                    return results;



                    function buildFunc() {
                        currentHead = headIn - headOut;

                        var headDays = getHeadDays({ locationId: locationId, groupId: groupId, callDate: null });

                        var totalWeight = headIn != 0
                            ? ((((headDays * expectedAdg) + payWtIn) / headIn) * currentHead) + payWtOut
                            : 0;


                        results.push({
                            id: id,
                            name: name,
                            headIn: headIn,
                            headOut: headOut,
                            headDays: headDays,
                            currentHd: currentHead,
                            totalWt: totalWeight
                        });
                    }

                    function reset() {
                        id = data[i].id();
                        name = data[i].name();
                        headIn = data[i].headIn();
                        headOut = data[i].headOut();
                        expectedAdg = data[i].expectedAdg();
                        payWtIn = 0;
                        payWtOut = 0;
                        weight = 0;
                    }
                });
            });
    }

function getHeadDays(params) {
    var VAL = 0;

    promise(params.a, params.b).then(function(data) {
        for (var i = 0; i < data.length; i++) {
            // Make calculation to determine VAL here                           
        }
    });

    return VAL;
}

init 函数在缓存中加载所需的实体(我正在使用 BreezeJs)进行查询。 getData 函数从数据库中获取按 id 排序的原始数据,这些数据用于确定 results 数组。随着数据的循环,只要每条记录的id相同,headIn、headOut、payWtIn和payWtOut都按记录字段递增,当前一个和当前的id不同,我们可以计算 totalWeight 并使用 buildFunc 函数将新记录推送到结果数组中。在 buildFunc 函数中,我们检索 headDays 以计算 totalWeight。 getHeadDays 函数将在许多其他函数中调用。请让我知道,如果你有任何问题。提前感谢您的帮助。

【问题讨论】:

  • 你不能进行异步操作并且make是同步的。相反,您需要学习如何以异步方式使用它进行编程,而 Promise 是一个很好的方法。您将希望从F1 返回一个承诺,以便F1 的调用者可以在承诺上使用.then() 来了解操作何时完成以及它返回的值。
  • 感谢您的及时回复。我真的希望我不会阅读任何“不能做”的消息,但不幸的是我不得不面对这个事实。悲伤但如此。 :( 我想我将不得不对代码进行重大更改。Ugrr!
  • 那么如何在 FOR 循环中使用 Promise?欢迎任何带有实际示例的想法。
  • 如果您向我们展示您在for 循环中尝试执行的操作(将代码添加到您的问题或开始一个新问题),我们可以提供建议。 “在for 循环中使用promise”这个问题太笼统了,有很多可能的含义和解决方案。
  • @jfriend00:我在帖子中预览了代码。谢谢。

标签: javascript promise q


【解决方案1】:

你不能。

如果您需要返回一个promise,那是因为在某些事件发生之前该值不可用,并且该函数将(或至少可能)在此之前返回。这就是应许的意义。

【讨论】:

  • 当然,你也必须考虑到违背的承诺...... sigh
  • 是的,我使用同步函数(promises)已经有一段时间了。我只是希望有办法解决这种情况。不幸的是,这不可能发生......
  • @RipHamilton 如果您可以在构建步骤中使用 regenerator 或类似项目(或仅针对 chrome 或 firefox 或 node),则可以使其 look 与 ES6 生成器异步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
相关资源
最近更新 更多