Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

105
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda