For Loop

时间:2018-04-21 08:01:44

标签: javascript asynchronous promise web3js

我试图在链式承诺中获取我的游戏的每个属性(每个属性都来自不同的异步调用)。

我的算法逻辑:

  1. 检查网络并获取智能合约地址
  2. 注册包含所有游戏地址的合约
  3. 获取游戏数量
  4. 对于每个游戏,执行一次aSync呼叫 每个属性
  5. 打印所有游戏和详细信息(此处我无法使用 获取更新的对象)
  6. 代码:

      var games = [];
      window.addEventListener('load', function() {
        // Check the Network and assign the smart contract address
    
        web3.eth.net.getId()
          .then(function(networkId) {
            let contractAddressRegistry;
            if (networkId == 1) {
              contractAddressRegistry = "0xQWERTYUIOPQWERTYUIOPQWERTY"
            } else {
              contractAddressRegistry = "0x12345678901234567890123456"
            }
            return contractAddressRegistry;
          })
          .then(function(contractAddressRegistry) {
            let contractRegistry = new web3.eth.Contract(contractAbiRegistry, contractAddressRegistry);
    
            contractRegistry.methods.numberOfGames().call()
              .then(function(numberOfGames) {
    
                for (let i = 0; i < numberOfGames; i++) {
                  let game = {};
                  game.propertyA = aSyncCallGetPropertyA(i); // Promise
                  game.propertyB = aSyncCallGetPropertyB(i); // Promise
                  game.propertyC = aSyncCallGetPropertyC(i); // Promise
                }
                games.push(game);
              })
          })
          .then(function() {
            console.log(games) // Empty
          })
      })
    

    我尝试过使用Promises.all(),但由于某些异步调用在then()内,我无法正确同步。

    如何确保让对象游戏充满其所有属性?

2 个答案:

答案 0 :(得分:2)

您应该像这样使用Promise.all。基本上,您需要在aSyncCallGetProperty中包装所有三个Promise.all异步调用,等待它们真正完成,然后将结果分配给对象game

whatever
    .then(function(contractAddressRegistry) {
        let contractRegistry = new web3.eth.Contract(contractAbiRegistry, contractAddressRegistry);
        return contractRegistry.methods.numberOfGames().call();
    })
    .then(function(numberOfGames) {
        return Promise.all(numberOfGames.map(() => {
            return Promise.all([
                aSyncCallGetPropertyA(),
                aSyncCallGetPropertyB(),
                aSyncCallGetPropertyC()
            ]).then(results => {
                let game = {};
                game.propertyA = results[0];
                game.propertyB = results[1];
                game.propertyC = results[2];
                return game;
            });
        }));
    })
    .then(function(games) {
        console.log(JSON.stringify(games));
    })

答案 1 :(得分:1)

@路易斯&#39;代码似乎没错,但我无法确定numberOfGames是什么。假设它是你问题中使用的整数(不是在另一个答案中处理的数组),这里是一个没有嵌套.then() s的进一步重新版本。

window.addEventListener('load', function() {
  web3.eth.net.getId()
              .then(networkId => networkId === 1 ? "0xQWERTYUIOPQWERTYUIOPQWERTY"
                                                 : "0x12345678901234567890123456")
              .then(contractAddressRegistry => new web3.eth.Contract(contractAbiRegistry, contractAddressRegistry).methods.numberOfGames().call())
              .then(numberOfGames => Promise.all(Array(numberOfGames).fill()
                                                                     .map(_ => Promise.all([aSyncCallGetPropertyA(),
                                                                                            aSyncCallGetPropertyB(),
                                                                                            aSyncCallGetPropertyC()]))))
              .then(function(games){
                      games = games.map(game => ({propertyA: game[0],
                                                  propertyB: game[1],
                                                  propertyC: game[2]}));
                      doSomethingWith(games);
                    });
  });