最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I Sum Array elements in every second - Stack Overflow

programmeradmin2浏览0评论

I'm trying to sum up the array of elements by every seconds. My array has 20 elements, and it should be summed up in 20seconds.

I'm using setTimeout in for loop but its not working , the loop finish before the first second. Anyway to achieve ?

for (var o = 0; o < 20; o++) {
   setTimeout(function () {
       tempPsum += array[o];
   }, 1000);
}

I'm trying to sum up the array of elements by every seconds. My array has 20 elements, and it should be summed up in 20seconds.

I'm using setTimeout in for loop but its not working , the loop finish before the first second. Anyway to achieve ?

for (var o = 0; o < 20; o++) {
   setTimeout(function () {
       tempPsum += array[o];
   }, 1000);
}
Share Improve this question edited Sep 7, 2020 at 10:42 Jamiec 136k15 gold badges141 silver badges199 bronze badges asked Sep 7, 2020 at 10:34 hatchedhatched 8652 gold badges11 silver badges47 bronze badges 3
  • Why would you want to wait a second before adding each array entry? – T.J. Crowder Commented Sep 7, 2020 at 10:37
  • @T.J.Crowder to display the sum of the array in HTML – hatched Commented Sep 7, 2020 at 10:39
  • 2 ...and what notifies the HTML that tempPsum has changed? – Jamiec Commented Sep 7, 2020 at 10:41
Add a ment  | 

5 Answers 5

Reset to default 7

Right, the loop finishes before the first setTimeout callback occurs. Your code schedules 20 callbacks that all occur, one after another, a second later.

You have two choices:

  1. Schedule each one a second later than the previous one, or

  2. Don't schedule the next one until the previous one finishes

#1 is simpler, so let's do that:

for (let o = 0; o < 20; o++) {
//   ^^^−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
   setTimeout(function () {
       tempPsum += array[o];
   }, 1000 * o);
//        ^^^^−−−−−−−−−−−−−−−−−−−−−−−−−−
}

By multiplying the delay time by o, we get 0 for the first timer, 1000 for the second, 3000 for the third...

Note the change from var to let. That way, there's a separate o for the callback to close over for each loop iteration. (See answers here, or...Chapter 2 of my new book. :-) )

If you can't use ES2015+ features in your environment, you can use the extra arguments to setTimeout instead:

for (var o = 0; o < 20; o++) {
   setTimeout(function (index) {
//                      ^^^^^−−−−−−−−−−−
       tempPsum += array[index];
//                       ^^^^^−−−−−−−−−−−
   }, 1000 * o, o);
//        ^^^^−−^−−−−−−−−−−−−−−−−−−−−−−−
}

That tells setTimeout to pass the third argument you give it to the callback as its first argument.

Ideal use case of setTimeout() is when you have to perform an operation once after a specific time frame. The scenario mentioned above requires same operation that is adding array element after a fixed time frame, so I believe setInterval() would be a better option.

var array = [1,2,3,4,5];
var tempSum = 0, i = 0;
var intrvl = setInterval( ()=> {
  tempSum += array[i++];
  console.log(tempSum)
  if(i === array.length)
    clearInterval(intrvl)
}, 1000)

This answer doesn't explain what the issue is, but offers an alternative to the other solutions. Instead of modifying the timeout using the index, you could add a sleep function that resolves a promise in a given amount of time.

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

Then loop through your array using for...of and sleep each iteration for a given amount of time.

let sum = 0;
for (const number of numbers) {
  await sleep(1000);
  sum += number;
}

This does require the code to be placed in an async function.

const randomInt = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const numbers = Array.from({length: 20}, () => randomInt(10, 99));
console.log("numbers =", ...numbers);

(async () => {
  let sum = 0;
  for (const number of numbers) {
    await sleep(1000);
    console.log(sum, "+", number, "=", sum += number);
  }
})();

@TJCrowder has said why your version doesn't work.

I will suggest another solution:

Another way: use setInterval

let numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

let tempPsum = 0

let i = 0

    let intervalId = setInterval(function () {
       tempPsum += numbers[i];
       i = i + 1;
       console.log(tempPsum);

       if (i == 20) {clearInterval(intervalId)}
   }, 1000);

I think you can use this approach:

var i = 0;
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20];
var sum = 0;
    
function myLoop() {         
  setTimeout(() => {
    sum = sum + arr[i];
    console.log(sum);
    i++;
    if (i < 20) {        
      myLoop();        
    }       
  }, 1000)
}
    
myLoop();

发布评论

评论列表(0)

  1. 暂无评论