0

When I make network call via axios, the consuming service does not await it

Executing function:

accountResolved: (atNumber, bkCode) => {
    return new Promise((resolve, reject) => {
      axios.get(`url/foo/bar`, {
        headers: {
          'Authorization': 'token',
        }
      })
      .then(
          (response) => {
            resolve(response.status === 200 ? true : false);
          },
          (error) => {
            console.log(error);
            resolve(false);
          })
        .catch((error) => {
          console.log(error);
          reject(error);
        });
    });
  },

Consuming Function

mapResolvedBankCode: (readCsvFileResponse, etransactBankCodes) => {
    return new Promise((resolve, reject) => {
      const readCsvFileResponseClone = [...readCsvFileResponse];
      readCsvFileResponseClone.forEach((item) => {

        for (let index = 0; index < etransactBankCodes.length; index++) {
          const bankCode = etransactBankCodes[index];

          CsvService.accountResolved(item.accountNumber, bankCode)
            .then(
              (result) => {
                if (result) {
                  console.log(`resolved account ${item.accountNumber}, with bank ${bankCode}`);
                  item.bankCode = bankCode;
                }
              },
            (error) => {
              console.error('mapResolvedBankCode', error);
              item.bankCode = 'err';
            })
            .catch((err) => {
              console.error(`error in account no. ${item.accountNumber}::: `, err);
              item.bankCode = 'err';
            });
        }

      });
      if (readCsvFileResponseClone && readCsvFileResponseClone.length > 0) {
        resolve(readCsvFileResponseClone);
      } else {
        reject('readCsvFileResponseClone not formed correctly');
      }
    });
  },

I expected that the executing function will be awaited by the consuming function but it isnt happening. The consuming function already returns a response before the axios network call commence

Caesar
  • 59
  • 1
  • 10

2 Answers2

0

How i see it is that readCsvFileResponseClone.forEach() is the first loop inside of which you have 2nd loop for (let index = 0; index < etransactBankCodes.length; index++) {} and in this loop is where you call the Executing Function.

forEach() is not an async fn, and as per the MDN docs there is no way to stop forEach(). And as per the doc you need to use for, for...of, and for...in and even Array methods like every(), some(), find(), and findIndex()

So i suggest you try using for() loop on readCsvFileResponseClone array, doing so the 1st loop should await the logic inside the 2nd loop in which you have Executing function before exiting from the 1st loop.

Nishant S Vispute
  • 713
  • 1
  • 7
  • 21
0

Like jfriend00 said, there is no await, so nothing will really block. Promises are just a different way to work with callbacks.

Although you can't block the foreach loop this way, you can however create a promise chain, see code below. This will resamble sequential execution. Or if you want concurrent calls to accountResolved, you could store all promises from the loop and then after the loop use Promise.allSettled.

mapResolvedBankCode: (readCsvFileResponse, etransactBankCodes) => {
    return new Promise((resolve, reject) => {
        const readCsvFileResponseClone = [...readCsvFileResponse];

        var chain = Promise.resolve();    // initial promise

        readCsvFileResponseClone.forEach((item) => {

            for (let index = 0; index < etransactBankCodes.length; index++) {
                const bankCode = etransactBankCodes[index];
                chain = chain       // chain with promise from previous loop
                    .then(() => {
                        console.log('calling accountResolved');
                        return CsvService.accountResolved(item.accountNumber, bankCode) // return promise
                    })
                    .then(
                        (result) => {
                            if (result) {
                                console.log(`resolved account ${item.accountNumber}, with bank ${bankCode}`);
                                item.bankCode = bankCode;
                            }
                        },
                        (error) => {
                            console.error('mapResolvedBankCode', error);
                            item.bankCode = 'err';
                        })
                    .catch((err) => {
                        console.error(`error in account no. ${item.accountNumber}::: `, err);
                        item.bankCode = 'err';
                    });
            }

        });

        chain.then(() => {
            if (readCsvFileResponseClone && readCsvFileResponseClone.length > 0) {
                resolve(readCsvFileResponseClone);
            } else {
                reject('readCsvFileResponseClone not formed correctly');
            }
        });
    });
}

// use 
mapResolvedBankCode(...).then( (...) => ... );
user7994388
  • 448
  • 3
  • 6