Search code examples
promisechaining

External variable access when chaining Promises


I have a big problem in JS.

I have a function where I make a promise chain. A promise is "added" to the last promise in a for loop. Inside this loop there are some variables. Each function of each then needs to access these variables, that is, their values corresponding to the correct for iteration.

The problem is, I believe, since the promise is executed when the functions ends, each promise will read the same values of those variables (which have the values of the last for iteration).

I don't want this to happen. How can I do to solve it?

I have written a code that mimics my problem:

function test() {
var p = Promise.resolve();
for (var i = 0; i < 10; i++) {
	var j = i * 10;
	p = p.then(function() {
		alert(j);
	});
}
  
p.then(function() {
	alert('finished');
})

}

test();

As you can see, each time the function inside then fires, it always reads value 90 of j, instead of reading all the correct values.

Thank you for your help


Solution

  • Change var to let and then each invocation of the loop will have its own set of variables.

    function test() {
        let p = Promise.resolve();
        for (let i = 0; i < 10; i++) {
        	let j = i * 10;
        	p = p.then(function() {
        		console.log(j);
        	});
        }
          
        p.then(function() {
        	console.log('finished');
        })
    }
    
    test();

    let is block scoped so each block (in this case each iteration of the for loop) gets its own version of the i and j variables. So, when you do your alert(j), it will be using the correct variable.

    FYI, I changed alert(j) to console.log(j) because using alert() can mess with asynchronous timing (since it blocks JS execution) whereas console.log() just reports and lets the code keep running so you get a better picture of how things actually run with console.log().