Home > Enterprise >  I don't know how to wait for the execution of complex function using await Promise.all to compl
I don't know how to wait for the execution of complex function using await Promise.all to compl

Time:04-17

const fetchPrice = async (symbols) => {
  const prices = {};
  await Promise.all(
    symbols.map(async (symbol) => {
      const priceInformation =
        (base.id, await base.fetch_ticker((Symbol = replacedSymbol)));
      prices[symbol] = priceInformation;
    })
  );
  return prices;
};

const PriceObj = await fetchPrice(SYMBOL_LIST);

console.log(PriceObj);

In the above code, I don't know how to wait for fetchPrice to be processed before executing console.log();.

The console.log(); only returns unexpected values, such as undefined or Promise.

(If I put console.log(prices); before return at the end of the fetchPrice function, then only this console.log(); returns the expected value, so the fetchPrice function itself is working).

I saw some information somewhere that return new Promise should be used, but it was too complicated for a beginner to understand.

How can I wait for fetchPrice to process and then display the last console.log(PriceObj); value correctly?

CodePudding user response:

The Array.map() you are using the iterate the symbols implicitly returns an array of undefined values. Since Promise.all() expects an array of promised wrapped values, and you want to create an object, return a pair of [symbol, priceInfo] from each call, and after they are resolved by Promise.all() convert them to an object using Object.fromEntries():

const fetchPrice = async (symbols) => {
  const prices = await Promise.all(
    symbols.map(symbol => 
      base.fetch_ticker(symbol)
        .then(priceInfo => [symbol, priceInfo])
    )
  );

  return Object.fromEntries(values);
};

const PriceObj = await fetchPrice(SYMBOL_LIST);

console.log(PriceObj);

CodePudding user response:

Here's a runnable version of your code where I've simulated fetch_ticker() as an asynchronous function that returns a promise that resolves in a random amount of time and modified some things in your code that seemed odd or incorrect.

function randInt(min, max) {
    const r = Math.random();
    return Math.floor((r * (max - min))   min);
}

function delay(t, v) {
    return new Promise(resolve => setTimeout(resolve, t, v));
}


// simulate base.fetch_ticker
const base = {
    fetch_ticker() {
        let t = randInt(100, 1000);
        return delay(t, t);
    }
}

const fetchPrice = async (symbols) => {
    const prices = {};
    await Promise.all(symbols.map(async (symbol) => {
        const priceInformation = await base.fetch_ticker(symbol);
        prices[symbol] = priceInformation;
    }));
    return prices;
};


async function run() {

    const SYMBOL_LIST = ["a", "b", "c", "d"];

    const PriceObj = await fetchPrice(SYMBOL_LIST);

    console.log(PriceObj);

}

run().then(result => {
    console.log("done");
}).catch(err => {
    console.log(err);
});


As you can see in my comments to your question, there were parts of your code that didn't make sense to me. It is unclear what you're trying to do with the (Symbol = replacedSymbol) part of this since Symbol is a built-in global and replacedSymbol is not shown in your code at all and it's unclear why you would be doing this assignment in the middle of passing arguments:

base.fetch_ticker((Symbol = replacedSymbol))

And, it's unclear why the base.id is involved in this:

const priceInformation = (base.id, await base.fetch_ticker((Symbol = replacedSymbol)));

This statement:

(base.id, await base.fetch_ticker((Symbol = replacedSymbol)))

will just evaluate to the the value of the second item in the comma list and the base.id will have no effect at all.

In my code example above, I've removed both of those elements since there's no explanation or reasoning provided for them.

  • Related