How to prevent event loop freeze on Nestjs?

Viewed 1249

I'm trying to create asynchronous task in NestJs. I want that after one request to some controller was made, my async task start begin your long job while loop, and then the node/nest process steel able to answer other requests of other controllers.

But when the async loop begin, all the other endpoints of Nest being freeze until de async task are done.

I already tryed to use setTimeout(), setInterval(), setIntermmediate(), queueMicrotask() and Promise.resolve()

My code:

// Async task:

private checkTime(baseTime: number, startTimeStamp: number){
   while(true){
      const elapsedTime = Date.now() - startTimeStamp
      console.log(`Elapsed time: ${elapsedTime}`)
      if(elapsedTime > baseTime){
          console.log(`Time excced!`)
          break;  
      }
   }
}

And I already try something like that:

queueMicrotask(() => this.checkTime(edge.baseTime, startedTimeStamp))

setTimeout(() => this.checkTime(edge.baseTime, startedTimeStamp), 0)

1 Answers

Use javascript generators

Code snippet:

function* longTask(time = 1000) {
  const startTime = Date.now();
  // divides the long task into smaller chunks
  yield startTime;

 while (Date.now() - startTime < time) {
    // process(): excute a small chunk of the task
    // and yields the control back to the caller
    yield Date.now() - startTime;
  }

}

function completeLongTask(lt) {
  const val = lt.next();
  if (!val.done) {
    setTimeout(() => {
      completeLongTask(lt);
    }, 0);
  }
}

function triggerTask() {
  const lt = longTask();
  completeLongTask(lt);
}

triggerTask();

Although the solution above works, I think you needn't use generators for your use case. See if this simpler solution works for you.

function checkTime(baseTime, startTimeStamp) {
  const currentTimeStamp = Date.now();
  const elapsedTime = currentTimeStamp - startTimeStamp;
  console.log(`Elapsed time: ${elapsedTime}`);
  if (elapsedTime > baseTime) {
    console.log(`Time excced!`);
    return;
  } else {
    setTimeout(() => {
      checkTime(baseTime, startTimeStamp);
    });
  }
}
Related