Home > Blockchain >  NodeJS - While loop until certain condition is met or certain time is passed
NodeJS - While loop until certain condition is met or certain time is passed

Time:11-16

I've seen some questions/answers very similar but none exactly describing what I would like to achieve. Some background, this is a multi step provision flow. In pretty short words this is the goal.

 1. POST an action.
 2. GET status based in one variable submitted above. If response == "done" then proceed. Returns an ID.
 3. POST an action. Returns an ID.
 4. GET status based on ID returned above. If response == "done" then proceed. Returns an ID.
 5. (..)

I think there are 6/7 steps in total.

The first question is, are there any modules that could help me somehow achieve this? The only requirement is that each attempt to get status should have an X amount of delay and should expire, marking the flow as failed after an X amount of time.

Nevertheless, the best I could get to, is this, assuming for example step 2:

GetNewDeviceId : function(req, res) {
    const delay = ms => new Promise((resolve, reject) => setTimeout(resolve, ms));
    var ip = req;
    async function main() {
        let response;
        while (true) {
            try {
                response = await service.GetNewDeviceId(ip);
                console.log("Running again for: "   ip   " - "   response)
                if (response["value"] != null) {
                    break;
                }
            } catch {
                // In case it fails
            }
            console.log("Delaying for: "   ip)
            await delay(30000);
        }

        //Call next step
        console.log("Moving on for: "  ip)
    }

    main();
}

This brings couple of questions,

  • I'm not sure this is indeed the best/clean way.
  • How can I set a global timeout, let's say 30 minutes, forcing it to step out of the loop and call a "failure" function.
  • The other thing I'm not sure (NodeJS newbie here) is that, assuming this get's called let's say 4 times, with different IP before any of those 4 are finished, NodeJS will run each call in each own context right? I quickly tested this and it seems like so.

CodePudding user response:

I'm not sure this is indeed the best/clean way.

It am unsure whether your function GetNewDeviceId involves a recursion, that is, whether it invokes itself as service.GetNewDeviceId. That would not make sense, service.GetNewDeviceId should perform a GET request, right? If that is the case, your function seems clean to me.

How can I set a global timeout, let's say 30 minutes, forcing it to step out of the loop and call a "failure" function.

let response;
let failAt = new Date().getTime()   30 * 60 * 1000; // 30 minutes after now
while (true) {
  if (new Date().getTime() >= failAt)
    return res.status(500).send("Failure");
  try {...}
  ...
  await delay(30000);
}

The other thing I'm not sure (NodeJS newbie here) is that, assuming this get's called let's say 4 times, with different IP before any of those 4 are finished, NodeJS will run each call in each own context right?

Yes. Each invocation of the function GetNewDeviceId establishes a new execution context (called a "closure"), with its own copies of the parameters req and res and the variables response and failAt.

  • Related