Home > Net >  NodeJs / NestJs wait for async to be done and return results
NodeJs / NestJs wait for async to be done and return results

Time:09-19

I have a controller on nestjs that is writing a job to the queue.
The job processing suppose to last between 100MS to 5000MS.
I don't want to disconnect the client until I have the answer.

How can I do that and not running a while loop? write now I have this very bad code:

@Post('job')
async job(@Body() request): Promise<JobRes>{
   const job = await this.bullQueue.add('hande', request);

   while(true){ //UGLY AND BAD
       const state = await job.getState();
       if(state == 'completed'){
          return await this.db.findByJobId(job.id);
       }
       await sleet(1_000);
   }
}

This solution require a lot of resources from the event loop and is not safe at all.
I'm looking for a better solution to hand the request untill I have response.

Thanks

CodePudding user response:

I don't know what your request, job or bullQueue is. But generally you have the following possibilities:

  1. make the job to be a promise -- ie bullQueue.add() must return a Promise<Promise<T>> or depending on what request is you may be able to turn it into a promise directly without adding it to some queue -- so you can do something like this

    const job = await this.bullQueue.add('hande', request);
    // const job = request.toPromise();   just some pseudo code, wrapping request into a promise 
    await job;
    
    ...
    
  2. make job emit an event when it's finished so you can do something like this

    const job = await this.bullQueue.add('hande', request);
    await new Promise(res => {
      //attach the event listener to job
      //and once the event is raised, resovle the promise
      job.on("completed", () =>{ res(); });
    })
    
    ...
    

If you cannot change the implementation of your job you are pretty much out of luck, ie you can only wait for your condition to become fulfilled ... See @Michael Lampu answer on how to make this a bit more structured ...

CodePudding user response:

Hei!

import { setTimeout } from "timers/promises"
const abc = async()=>{
   while((await job.getState())!=='completed') await setTimeout(500)
   return await this.db.findByJobId(job.id);
}

This approach has little to do with mind, while will do its work. See comments.

  • Related