如何在异步函数中求和Javascript数组的值?

Bre*_*dan 2 javascript promise angularjs protractor angular-promise

我正在使用Angularjs Protractor进行e2e测试,我正在尝试对列中的值求和.在循环内部,我可以打印出每个值都很好,但我无法弄清楚如何将它们全部添加.如果我尝试在for循环后返回total,那么它是未定义的.

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;
  });
};
Run Code Online (Sandbox Code Playgroud)

Ben*_*aum 6

另一个(现在是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);
    });
}
Run Code Online (Sandbox Code Playgroud)

或者,如果你不是Array#reduce粉丝,你可以总结一个for循环.

然后,用法是这样的:

getTotal().then(function(total){
    alert(total); // total value available here
});
Run Code Online (Sandbox Code Playgroud)

请注意,像Bluebird这样的外部承诺库可以让您:

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

哪个更干净.