Web3:等待循环内的所有异步调用完成

时间:2018-04-07 15:56:22

标签: javascript asynchronous async-await ethereum web3js

我正在使用Web3获取智能合约列表,然后迭代(循环)每个合同以获取智能合约的多个变量。不幸的是,一旦我的循环中的所有异步调用都完成,我就无法执行函数。

逻辑:

  1. 获取游戏数量
  2. 对于i = 0,直到i <0。游戏
    • 获取智能合约地址(来自Smart Contract)
    • 获取开始时间值(来自智能合约)
    • 获取结束时间值(来自智能合约)
  3. (完成循环的所有调用后)
  4. 按开始时间订购游戏
  5. 展示游戏
  6. 当我循环后执行console.log(contractInstanceGame)(步骤3)时,由于之前的调用未完成,因此数组为空。

    代码:

    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 < 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);
      }
    

    编辑: 我试过的解决方案的例子:

    在调用本身上使用then()不起作用,因为我遇到以下错误: inpage.js:14未捕获错误:MetaMask Web3对象不支持没有回调参数的eth_call等同步方法。有关详细信息,请参阅https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client

    contractInstanceRegistry.numberOfGames()
    .then(function(x){
      console.log(x);
    });
    

    我也试过Promisifed并使用await,但我遇到了错误:Uncaught SyntaxError:await仅在异步函数中有效

    let numberOfGames = promisify(cb => contractInstanceRegistry.numberOfGames(cb));
    let numberOfGamesX = await numberOfGames;
    

0 个答案:

没有答案