angularjs - How do I sum the values of a Javascript array in an asynchronous function? - Stack Overflow

I'm using Angularjs Protractor for e2e tesing, and I'm trying the sum the values in a column.

I'm using Angularjs Protractor for e2e tesing, and I'm trying the sum the values in a column. Inside the loop I can print out each value fine, but I can't figure out how to add them all. If I try to return total after the for loop, it's undefined.

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

I'm using Angularjs Protractor for e2e tesing, and I'm trying the sum the values in a column. Inside the loop I can print out each value fine, but I can't figure out how to add them all. If I try to return total after the for loop, it's undefined.

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;
  });
};
Share edited Dec 25, 2014 at 11:31 Benjamin Gruenbaum 277k89 gold badges520 silver badges517 bronze badges asked Apr 7, 2014 at 17:15 BrendanBrendan 1,4714 gold badges18 silver badges37 bronze badges 3
  • Are these operations async? If they are, you simply can't synchronously return the total from a series of async operations? If the operations aren't async, then I'm trying to figure out why you're even trying to use promises as there must be a simpler way. – jfriend00 Commented Apr 7, 2014 at 17:22
  • The operations are async, that's what I'm mostly confused about. – Brendan Commented Apr 7, 2014 at 17:25
  • 3 Then, you simply cannot EVER synchronously return the total from getTotal() because it simply isn't done yet when getTotal() returns. You will need to either have getTotal() return a promise and resolve that promise when the total is done being calculated or have getTotal() take a callback and call that callback and pass it the total when it's done calculating. You have to restructure it. – jfriend00 Commented Apr 7, 2014 at 17:29
Add a ment  | 

2 Answers 2

Reset to default 6

The other (now deletec) answer has the right idea but bulky and incorrect promise code. Using $q.all (Which is Promise.all in ES6 plaint promise implementations is how we wait for an array of promises to plete:

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

Alternatively, if you're not an Array#reduce fan you can sum with a for loop.

Then, usage is something like:

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

Note, an external promise library like Bluebird would let you do:

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

Which is even cleaner.

Protractor has a buil-in map function.

I would remend you to do something like this:

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745098308a4611116.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信