I am polling the price of various Ethereum smart contracts with Web3.js. This is done asynchronously, and many times the values get returned out of order, which means they get pushed to the new array in the wrong order. I want to push values to a new array inside a forEach loop so that I can update values on a page using jQuery. What is the best way to keep things in order?
Steps Taken:
First I splice all of the contracts in order into an array.
var Contracts = [];
Contract.splice(0, 0, EthereumContract.at("0x2a50fb3396455717043ae5aa631d362c94fe13e1"));
Contract.splice(1, 0, EthereumContract.at("0x69ec0658ff334789c7f57edc3a2f28adef1c0ef3"));
Contract.splice(2, 0, EthereumContract.at("0x4d2bab147c32c75c8c9277182e64c69e14cb9f3c"));
Contract.splice(3, 0, EthereumContract.at("0xcd56f2c89128ad71cfd87b0fc78c9e26990b0f66"));
Then I make a new array 'TheCurrentPrice' that should receive the price of each contract.
var TheCurrentPrice = [];
Now I loop through the array in order and apply the Price method to the contracts in the array. I push the returned results into a new array. Unfortunately, it sometimes gets responses out of order and gets pushed incorrectly into the new array.
Contract.forEach(function (Contract) {
Contract.Price(function (error, result) {
TheCurrentPrice.push(result);
});
});
Solution:
Alnitak gave the correct answer, but with incorrect syntax in case anyone tries this in the future.
function PricePromise(Contract) {
return new Promise((resolve, reject) => {
Contract.Price(function (error, result) {
if (error) {
reject(error);
console.log("Price Error");
} else {
resolve(result);
console.log("Price " + result);
}
});
});
};
Promise.all(Contract.map(PricePromise))
.then(function(Price) {
('#Product-Price-1').attr('data-price', Price[0] / 1000000000000000000);
/*This uses jQuery to update a custom data-* attribute in HTML5. Price[0] is of course the first entry in the array of prices retrieved with the promise.*/
...
});
What I don't quite get is why resolve(result) allows me to forgo a forEach loop of the Price method, but you don't need the forEach, this is the correct syntax.