【问题标题】:How do I sum the values of a Javascript array in an asynchronous function?如何在异步函数中对 Javascript 数组的值求和?
【发布时间】:2014-05-20 01:54:19
【问题描述】:

我正在使用 Angularjs Protractor 进行 e2e 测试,并且我正在尝试对列中的值求和。在循环内部,我可以很好地打印出每个值,但我不知道如何将它们全部添加。如果我尝试在 for 循环之后返回总计,则它是未定义的。

function getTotal() {
  ptor.findElements(protractor.By.className('col33')).then(function(promColCells) {
    var total;
    for (var i = 2; i < promColCells.length; i += 2) {
      promColCells[i].getText().then(function(promCellString) {
        total += parseFloat(promCellString);
      });
    }
    return total;
  });
};

【问题讨论】:

  • 这些操作是异步的吗?如果是,您根本无法从一系列异步操作中同步返回总数?如果操作不是异步的,那么我试图弄清楚你为什么还要尝试使用 Promise,因为必须有更简单的方法。
  • 操作是异步的,这就是我最困惑的地方。
  • 那么,您根本无法从getTotal() 同步返回total,因为当getTotal() 返回时它还没有完成。您将需要让getTotal() 返回一个承诺并在完成计算total 时解决该承诺,或者让getTotal() 接受回调并调用该回调并在计算完成时将总数传递给它。你必须重组它。

标签: javascript angularjs promise protractor angular-promise


【解决方案1】:

另一个(现在是 deletec)答案有正确的想法,但承诺代码庞大且不正确。使用$q.all(这是 ES6 投诉承诺实现中的 Promise.all 是我们等待一系列承诺完成的方式:

function getTotal() {
    // we return the continuation here
    return ptor.findElements(protractor.By.className('col33')).then(function(cells) {
        // wait for all cells  
        return $q.all(cells.map(function(cell){ return cell.getText()}));
    }).then(function(cellTexts){
        return cellTexts.reduce(function(x,y){ return x + Number(y);},0);
    });
}

或者,如果您不是 Array#reduce 的粉丝,您可以使用 for 循环求和。

然后,用法是这样的:

getTotal().then(function(total){
    alert(total); // total value available here
});

注意,像 Bluebird 这样的外部 Promise 库可以让您这样做:

return Promise.cast(ptor.findElements(protractor.By.className('col33')))
    .map(function(cell){ return cell.getText(); })
    .reduce(function(x,y){ return x+Number(y); });

这样更干净。

【讨论】:

  • 非常感谢,我现在明白了。是否有额外/缺失的大括号或其他东西?我收到 unexpected token } 错误。
  • 老实说,我不知道,我在 Stack Overflow 中输入了它,没有测试它 - 只是想通过一个点,让我追一秒。
  • 第 5 行可能缺少)
【解决方案2】:

量角器具有内置地图功能。

我建议你这样做:

function getTotal() {
  // The same as element.all(by.css('.col33')). It will return
  // a promise that resolves to an array os strings.
  return $$('.col33').map(function(cell){
    return cell.getText();
  }).
  then(function(values){
     // Values is an Array.<string> parse the ints and return the value.
     var result = 0;
     values.forEach(function(val){
       result += parseInt(val, 10);
     });
     return result;
  });
};

getTotal.then(function(total) {
});

【讨论】:

  • 谢谢安德烈斯,这很有帮助
猜你喜欢
  • 2021-12-20
  • 1970-01-01
  • 2022-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-24
  • 2011-05-19
相关资源
最近更新 更多