title: Web3: Wait all async calls within a loop are completed
body: <p>I am using Web3 to get a list of smart contract and then iterate (loop) through each of them to get multiple variables of the smart contracts. Unfortunately, I am not able to execute a function once all the async calls within my loop are done.</p>
  
  <p>Logic:</p>
  
  <ol>
  <li>Get the number of Games</li>
  <li>For i = 0 until i &lt; Games
  
  <ul>
  <li>Get the smart contract address (from Smart Contract)</li>
  <li>Get the Start Time value (from Smart Contract)</li>
  <li>Get the End Time value (from Smart Contract)</li>
  </ul></li>
  <li>(Once all calls of the loop are done)</li>
  <li>Order the Games by Start Time</li>
  <li>Display the Games</li>
  </ol>
  
  <p>When I do console.log(contractInstanceGame) (step 3) after my loop, the array is empty as the previous calls are not completed.</p>
  
  <p>Code:</p>
  
  <pre><code>var contractInstanceGame = [];
  
  contractAddressRegistry = '0xc0b55bff524b953a5248ccb5a60b00647052ae8b';
  
  // Fetch all the contract addresses
  let contractRegistry = web3.eth.contract(contractAbiRegistry);
  let contractInstanceRegistry = contractRegistry.at(contractAddressRegistry);
  
  contractInstanceRegistry.numberOfGames(function(err, res) {
    if (!err) {
      let numberOfGames = res.toNumber();
      for (i = 0; i &lt; numberOfGames; i++) {
        let contractGame = web3.eth.contract(contractAbiGame);
        contractInstanceRegistry.games(i, function(err, res) {
          if (!err) {
            // Create the object
            contractInstanceGame[i] = [];
            contractInstanceGame[i]['Caller'] = contractGame.at(res);
            contractInstanceGame[i]['Address'] = res;
  
            // Get the Start Time
            contractInstanceGame[i]['Caller'].startTime(function(err, res) {
              if (!err) {
                contractInstanceGame[i]['StartTime'] = res.toNumber();
              } else {
                console.error("Could not get the Game start time: " + err);
              }
            });
  
            // Get the End Time
            contractInstanceGame[i]['Caller'].endTime(function(err, res) {
              if (!err) {
                contractInstanceGame[i]['EndTime'] = res.toNumber();
              } else {
                console.error("Could not get the Game end time: " + err);
              }
            });  
          } else {
            console.error("Could not get the Game contract address: " + err);
          }
        });
      }
  
      console.log(contractInstanceGame);
      // Perform the Order of contractInstanceGame by Start Time`
      // Display contractInstanceGame
    } else {
      console.error("Could not get the number of Games: " + err);
    }
  </code></pre>
  
  <p>EDIT:
  Examples of the solutions I tried:</p>
  
  <p>Using then() on the call itself does not work as I am facing the following error:
  inpage.js:14 Uncaught Error: The MetaMask Web3 object does not support synchronous methods like eth_call without a callback parameter. See <a href="https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client" rel="nofollow noreferrer">https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client</a> for details.</p>
  
  <pre><code>contractInstanceRegistry.numberOfGames()
  .then(function(x){
    console.log(x);
  });
  </code></pre>
  
  <p>I also tried to Promisifed and use await, but I am facing the error: Uncaught SyntaxError: await is only valid in async function</p>
  
  <pre><code>let numberOfGames = promisify(cb =&gt; contractInstanceRegistry.numberOfGames(cb));
  let numberOfGamesX = await numberOfGames;
  </code></pre>