Andon Mitev
Andon Mitev

Reputation: 1504

Await nested loops - make outer loop to wait for inner to complete async requests

I have following script:

for (const block of blocks) {
      const [chunks, blockHeader] = await this.getChunksFromBlock(block);

      const transactions = await this.getTransactionsFromChunks(chunks);

      for (const transaction of transactions) {
        const res = await this.processTransactionActions(transaction, blockHeader);
      }
    }

And I'm trying to make processTransactionActions to wait for requests 1 by 1 before goes to next and make outer loop to wait for inner to finish before going for another iteration, i have been really stucked in this.

Right now behavior: outer loop is not waiting for inner to finish and for me is important to process there requests in sequence

And this is processTransactionActions:


async processTransactionActions(tx, blockHeader) {
    return tx.actions.map(async (action) => {
      const actionType = Object.keys(action)[0];

      if (actionType === ACTION_TYPE.FUNCTION_CALL) {
        try {
          const { method_name, args } = action[actionType];

          switch (method_name) {
            case METHOD_TYPE.INIT: {
              const initTx = createNearHTLC(args, tx, blockHeader);

              const claim = await this.htlcService.create(initTx);

              if (claim) {
                console.log('found init');
              }

              return claim;
            }
            case METHOD_TYPE.CLAIM: {
              const claimTx = createClaim(args, tx, blockHeader);

              return await this.htlcService.findAndSetClaimTx(
                { secretHash: claimTx.secretHash, 'raw.contractAddress': claimTx.contractAddress },
                claimTx.claimTx,
              );
            }
            case METHOD_TYPE.REFUND: {
              const refundTx = createRefund(tx, blockHeader);

              const refunded = await this.htlcService.findAndSetRefundTx(
                { 'raw.contractAddress': refundTx.contractAddress },
                refundTx.refundTx,
              );

              if (refunded) {
                console.log('found refunded');
              }

              console.log('no refund');

              return refunded;
            }
            default:
              return;
          }
        } catch (error) {
          if (error.code === 11000) {
          } else {
            throw error;
          }
        }
      }
    });
  }

Upvotes: 0

Views: 536

Answers (1)

Jordan
Jordan

Reputation: 24

As you have it all should work fine. Validate inside your procressTransactionActions function that you are awaiting any async logic there.

async function sleep(ms) {
    return new Promise((res) => {
    setTimeout(res, ms)
  })
}

(async () => {

    let blocks = [1,2,3,4,5,6,8]
    for (const block of blocks) {
       await sleep(100)

            console.log("SLEPT 100")
      await sleep(500)
      
            console.log("SLEPT 500")

      for (const transaction of blocks) {
        await sleep(1000)
        console.log("SLEPT 1000")
      }
    }

})()

Upvotes: 1

Related Questions