Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

104
Visualizações
Promise.all convert result with parameter from nested loop

The following loop to call an async function, here a smart contract interaction using web3. I want to get the balance of an array of token by calling balanceOf() and convert it subsequently with the attached usdrate. For parallel processing I am using Promise.all. Obviously, the function below Promise.all() with access [I % currency.length] does not work, since sorted result is not guaranteed.

My question is, how can I multiply the amounts with the correct usdrates attached to the tokens and still use Promise.all?

currencies = [{
    contract: token1,
    usdrate: 0.5
  },
  {
    contract: token2,
    usdrate: 1.0
  },
  {
    contract: token3,
    usdrate: 1.05
  },
  {
    contract: token4,
    usdrate: 1.10
  },
  {
    contract: token5,
    usdrate: 1.40
  },
  {
    contract: token6,
    usdrate: 1.0
  },
  {
    contract: token7,
    usdrate: 1.0
  }
];
}

async function getUsdWealthAsync(addresses) {
  var totalWealth = 0;
  var amountPromises = [];
  for (var j = 0; j < currencies.length; j++) {
    for (var i = 0; i < addresses.length; i++) {
      amountPromises.push(currencies[j].contract.methods.balanceOf(addresses[i]).call());
    }
  }
  await Promise.all(amountPromises).then(function(amounts) {
    for (var i = 0; i < amounts.length; i++) {
      amounts[i] = Number.parseInt(amounts[i]);
      totalWealth += (amounts[i] / 100) * currencies[i % currencies.length].usdrate;
    }
  })
  return totalWealth;
}

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

async functions always return a Promise, you can define an async function that receives an address and a currency and returns a Promise that has the calculation done already, so you don't have index troubles. Something like


async function getAmount(currency, address) {
   const amount = await currency.contract.methods.balanceOf(address).call();
   return amount * currency.usdrate;
}


async function getUsdWealthAsync(addresses) {
  const amountPromises = [];
  for (const currency of currencies) {
    for (const address of addresses) {
      amountPromises.push(getAmount(currency,address)/*Remember, calling this funciton returns a Promise*/);
    }
  }
  const realAmounts = await Promise.all(amountPromises)
  return realAmounts.reduce((total,current) => total+current, 0);
}


Where the last line with the reduce call is supposed to sum all the amounts you have

about 4 years ago · Juan Pablo Isaza Relatório

0

Why not use a nested Promise.all() to bundle all of the asynchronous calls for a particular currency under a single Promise? By doing this, you also retain the index alignment for processing the response.

async function getUsdWealthAsync(addresses) {
    let totalWealth = 0;
    let amountPromises = [];

    // For each of the currencies...
    for (var j = 0; j < currencies.length; j++) {
        // Create a set that will hold balance promises for this currency.
        const balancePromisesForCurrency = [];
        for (var i = 0; i < addresses.length; i++) {
            // Create those promises and add them to the set.
            balancePromisesForCurrency.push(
                currencies[j].contract.methods.balanceOf(addresses[i]).call()
            );
        }
        // Create a new promise that resolves to the list of balance results, ​
        // index-aligned to the addresses, for this currency. Add that Promise
        // to the set of per-currency Promises, index-aligned to the currencies
        // array.
        amountPromises.push(Promise.all(balancePromisesForCurrency));
    }

    // Create a new cumulative promise from the `amountPromises` array.
    await Promise.all(amountPromises).then(function (amountsForCurrency) {
        // For each of the balance lists received...
        amountsForCurrency.forEach((amounts, amountsIndex) => {
            // Get the corresponding currency.
            const currency = currencies[amountIndex];

            // Total up the balances scaled by the currency's USD rate.
            amounts.forEach((amount, idx) => {
                totalWealth += (+amount / 100) * currency.usdrate;
            });
        });
    })

    return totalWealth;
}```
about 4 years ago · Juan Pablo Isaza Relatório

0

You have other great answers.

Another way could be that, you can attach the USD rate along with the result from the balanceOf in the promise itself, And then while resolving the promises, you can access the USD rate directly.

Maybe something like this:

async function getUsdWealthAsync(addresses) {
  var totalWealth = 0;
  var amountPromises = [];
  for (var j = 0; j < currencies.length; j++) {
    for (var i = 0; i < addresses.length; i++) {
      const { usdrate, contract } = currencies[j];
      amountPromises.push(
        contract.methods.balanceOf(addresses[i]).call()
          .then((amount) => ({ amount, usdrate }))
      );
    }
  }

  const amounts = await Promise.all(amountPromises);

  for (var i = 0; i < amounts.length; i++) {
    const { amount, usdrate } = amounts[i];
    amount = Number.parseInt(amount);
    totalWealth += (amount / 100) * usdrate;
  }

  return totalWealth;
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda