0

I have a for-loop which contains some local variables n that is declared inside the loop. So I expected the value of n to be destroyed once the program goes out of the loop.

However, it appears that the value of n is still available outside of the for-loop. Why is that? Also, when should I expect the value of n (also the value k if uncommented) to be destroyed?

const delayHelper = require('./delayExecutor')

async function main() {
  let promises = [];
  let records = [1, 2, 3, 4];

  for(let i = 0; i < records.length; i++) {
    let n = 1000 + records[i];
    // let k = 123;
    promises.push(delayHelper.delayResolve(() => records[i], 1000).then(data => data + n))
  }

  console.log(await Promise.all(promises));   //print: [ 1002, 1004, 1006, 1008 ]
}

main()
//delayExecutor.js

let delayedResolve = (fun, ms) => {
  return new Promise((y, n) => {
    setTimeout(() => {
      y(fun());
    }, ms);
  });
};

exports.delayResolve = delayedResolve;
chakwok
  • 980
  • 8
  • 21

3 Answers3

0

How did you find that n is accessible from outside of the loo? I executed you code and tried to access n outsize of the loop. I get n is undefined error. Which is totally expected.

Now, the garbage collector decides when the unused memory needed to be garbage collected. You can search for V8 garbage collector.

Shihab
  • 2,641
  • 3
  • 21
  • 29
  • I'm thinking that because the `console.log` is able to access the value of `n` and prints [1002, 1004, 1006, 1008]. My expectation is that the value of `n` should somehow be put inside the `promises` array to be available in the `.then` block – chakwok Dec 03 '19 at 10:09
  • 1
    You mean, why the value of `n` is accessible from `.then`? Because, `n` will behave like global to all the nested scope inside for loop! You are calling the `delayHelper.delayResolve` from inside the for loop's scope. – Shihab Dec 03 '19 at 10:18
0

There are couple of concepts to be noted here. 1. Closure scope, 2. Block Scope

when ever you are accessing n in the inner function definitions, the variable is kept alive in closure scope for that inner function until it is no longer needed,

The usage of let to declare n will create a new variable in the block scope(for loop here) which will be locked to the inner function in that corresponding iteration.

One more thing you can experiment is use var to declare n which will yield a different result - [1005,1006,1007,1008]. This is because var is not a block scoped declaration hence it will not create a new variable for each iteration of the loop. The final value of n by the time the loop ends is 1004 and that will be used in your logic data => data + n

and for the second part of your question - As far as I know, all the variable references will be cleared at the end of the function. Since your n is locked in the Closure scope of the inner function data => data = n the n value will be cleared once that gets executed.

pranay kumar
  • 404
  • 3
  • 8
-1

With Promise.all promises will process parallel and results will resolve (or reject)

let delayedResolve = (fun, ms) => {
  return new Promise((y, n) => {
    setTimeout(() => {
      y(fun());
    }, ms);
  });
};


Promise.all([1, 2, 3, 4].map(async item=>await delayedResolve(()=> item, 1000)+1000+item))
.then(results=>console.log(results));

The code will first process for each promise and then appear all results. If you looks for sequential process, you need promise chaining.

Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37