Reputation: 53873
I've got a simple javascript loop and a function with a callback in there and I'm struggeling with adding
console.log(accounts); // logs this: ["123", "456"]
for (var i = 0; i < accounts.length; i++) {
var currentAccount = accounts[i];
console.log(currentAccount); // first logs "123" and then "456" as expected
meta.getBalance.call(account, {from: currentAccount}).then(function(value) {
console.log(currentAccount); // logs "456" twice
console.log(value.value()); // logs the same value corresponding to "123" twice
});
}
I presume that it logs "456" twice within the callback because it is an async call or something. But I'm unsure how I can solve this.
Any idea?
[EDIT]
I added one more console.log
to it, which logs the value returned by the callback. To my surprise, that logs the same value twice, which corresponds to 123, instead of to 456. WHY OH WHY?! How in godsname can that be?!
Upvotes: 1
Views: 46
Reputation: 933
You can pass your current value to a function, that return a function that gets called and has access to your value. Thats called Closures.
var accounts = ["123", "456"];
for (var i = 0; i < accounts.length; i++) {
var currentAccount = accounts[i];
console.log(currentAccount); // first logs "123" and then "456" as expected
promise('account', {from: currentAccount}).then(currentAccount => res => {
console.log(currentAccount) // 123, then 456
});
}
function promise() {
return new Promise((res, rej) => res());
}
Upvotes: 0
Reputation: 1744
In the callback you log the currentAccount
variable, which comes from the outer scope and is being assigned in the for loop.
Most likely, when your async call returns from its first call (made when currentAccount was "123"), currentAccount has already taken the value of the 2nd array element "456" inside the for loop.
Can you try to log the value
argument passed to the callback instead? You should see 2 distinct values being returned, one for account "123" and another for account "456".
Upvotes: 0
Reputation: 5357
You can use a closure.
function cbGenerator(account) {
return function(value) {
console.log(account);
}
}
Later...
for (var i = 0; i < accounts.length; i++) {
var currentAccount = accounts[i];
console.log(currentAccount);
var cb = cbGenerator(currentAccount);
meta.getBalance.call(account, {from: currentAccount}).then(cb);
}
Upvotes: 3
Reputation: 1674
Call your function inside IIFE
console.log(accounts); // logs this: ["123", "456"]
for (var i = 0; i < accounts.length; i++) {
var currentAccount = accounts[i];
console.log(currentAccount); // first logs "123" and then "456" as expected
(function(currentAccount){
meta.getBalance.call(account, {from:currentAccount}).then(function(value) {
console.log(currentAccount);
});
})(currentAccount);
}
Upvotes: 0