0

I have a POST API with some logic inside of it as below :

  app.post('/', async (req: Request, res: Response) => {
     const tasksRequest = req.body as TasksRequest;
     let tasks: Promise<any>[] = []

     tasks = tasksRequest.tasks.map((t) => processTask(t, tasksRequest.configs));
     await Promise.all(tasks);
  });

and below is the processTask function :

function processTask(task: Task, configs: Configs) {
  return new Promise<void>((resolve, reject) => {
    try {
      const fileName = './output/' + task.tag + 's.json';

      fetch(configs.Host + configs.APIsBasePrefix + task.parentResource + task.mostRelatedPath, {
        method: 'GET'
      }).then(result => {
        result.json().then(jsonResult => {
          fs.writeFile(fileName, JSON.stringify(jsonResult), function () {
            console.log('finished writing :' + fileName);
            resolve();
          });
        }).catch(err => reject(err));
      }).catch(err => reject(err));


    } catch (err) {
      console.log(err);
    }
  });
}

The issue is that I'm not able to make my server wait for all the promises to finish before sending the response back using the await Promise.all(tasks);

I tried many things and that was my latest approach.. Is there anything I'm missing?

Thanks in advance!

Changing my implementation many times, used libraries like fs.promise but with no luck.

UPDATE :

I tried also the below to make the code more readable :

app.post('/',  (req: Request, res: Response) => {
  const tasksRequest = req.body as TasksRequest;
  let tasks = []

  tasks = tasksRequest.tasks.map( (t) =>  processTask(t, tasksRequest.configs));

  //const temp = (processTask(tasksRequest.tasks[0],tasksRequest.configs));
  console.log(tasks);
  Promise.all(tasks).then(res=>{
    console.log('After awaiting');
  });
  

});

async function processTask(task: Task, configs: Configs) {
  try {
    const fileName = './output/' + task.tag + 's.json';

    const result = await fetch(configs.Host + configs.APIsBasePrefix + task.parentResource + task.mostRelatedPath, {
      method: 'GET'
    });

    const jsonResult = await result.json();
    return fs.promises.writeFile(fileName, JSON.stringify(jsonResult));

  } catch (err) {
    console.log(err);
  }
}

  • 1
    In `.then(result => {` you don't return the next promise. See [When should I use a return statement in ES6 arrow functions](https://stackoverflow.com/q/28889450). Thus you break the promise chain and you never wait for the inner promise. Also related, any time you see `.then()` nested in another `then()` that's very likely a problem. See [Aren't promises just callbacks?](https://stackoverflow.com/q/22539815) – VLAZ May 23 '23 at 09:04
  • use the Promise version of `fs` and your code will be far easier to write – Jaromanda X May 23 '23 at 09:08
  • looks OK - (disregard what I said later) – Jaromanda X May 23 '23 at 09:13
  • "*make my server wait for all the promises to finish before sending the response back*" - wait, where's the code that is sending the response back at all? – Bergi May 24 '23 at 02:40
  • And yeah, the rewritten code looks much better (avoiding the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)), you should definitely use that! – Bergi May 24 '23 at 02:42
  • Where are you sending back the response? – slebetman May 24 '23 at 02:51

1 Answers1

0

This is the problem I saw, I don't know if it can help you. If there is still a problem, it is better to debug it. It is better to provide logs

1

function processTask(task: Task, configs: Configs) {
  return new Promise<void>((resolve, reject) => {
    try {
      const fileName = './output/' + task.tag + 's.json';

      fetch(configs.Host + configs.APIsBasePrefix + task.parentResource + task.mostRelatedPath, {
        method: 'GET'
      }).then(result => {
        result.json().then(jsonResult => {
          // fs.writeFile(fileName, JSON.stringify(jsonResult), function () {
          fs.writeFile(fileName, JSON.stringify(jsonResult), function (err) {
            if(err){
              reject(err)
            }else{
              console.log('finished writing :' + fileName);
              resolve();
            }
          });
        }).catch(err => reject(err));
      }).catch(err => reject(err));


    } catch (err) {
      console.log(err);
    }
  });
}

2

// app.post('/',  (req: Request, res: Response) => {
app.post('/', async  (req: Request, res: Response) => {
  const tasksRequest = req.body as TasksRequest;
  let tasks = []

  tasks = tasksRequest.tasks.map( (t) =>  processTask(t, tasksRequest.configs));

  //const temp = (processTask(tasksRequest.tasks[0],tasksRequest.configs));
  console.log(tasks);
//  Promise.all(tasks).then(res=>{
 await Promise.all(tasks).then(res=>{
    console.log('After awaiting');
  });
  

});