0

I have a requirement to execute several parallel functions

First functions: Database get operation ie find inventory details from database

Second functions: Process db results and save the result as a file

I am using two promise all, back to back to execute the above functions, I don't feel like this is the correct way to do this. Is there a better way of handling these function calls. I am getting the result as per below code but want to know any other way.

Doing it following way:

let allQuery = {
  sql: "SELECT * from inventory",
};
let inventoryQuery = {
  sql: "SELECT * from inventory where inventory='1'",

};
let nearbyQuery = {
  sql: "SELECT * from inventory where inventory='2",

};
let firstPromises = [dbService.fetch(allQuery),
  dbService.fetch(inventoryQuery),
  dbService.fetch(nearbyQuery)
];
Promise.all(firstPromises)
    .then((values) => {
      let all = values[0];
      let inventory = values[1];
      let nearby = values[2];
      let fileKey1 = folderName + '/' + all.QueryExecutionId + '.csv';
      let fileName1 = all.QueryExecutionId + '.csv';
      let fileKey2 = folderName + '/' + inventory.QueryExecutionId + '.csv';
      let fileName2 = inventory.QueryExecutionId + '.csv';
      let fileKey3 = folderName + '/' + nearby.QueryExecutionId + '.csv';
      let fileName3 = nearby.QueryExecutionId + '.csv';
      let secondPromises = [s3Service.s3StreamDownload(bucketName, fileKey1, fileName1),
        s3Service.s3StreamDownload(bucketName, fileKey2, fileName2),
        s3Service.s3StreamDownload(bucketName, fileKey3, fileName3)
      ];
      Promise.all(secondPromises)
          .then((values) => {
            console.log('Do later operation');

          }).catch((error) => {
        debug(`Error in promises ${error}`);

      });

    }).catch((error) => {
  debug(`Error in promises ${error}`);

});
Dibish
  • 9,133
  • 22
  • 64
  • 106
  • 1
    It looks mostly reasonable, though I'd prefer to `return` the Promise than to use the callback anti-pattern (and avoid the `catch`) – CertainPerformance Mar 17 '20 at 09:38
  • 1
    Also, you could use parameter destructuring to make it cleaner: `.then(([all, inventory, nearby]) => {})` instead of `.then((values) => {})`. That way you can get rid of manually defined variables with the same names – Sebastian Kaczmarek Mar 17 '20 at 09:42
  • You should [flatten that promise chain](https://stackoverflow.com/a/22000931/1048572). Otherwise it's fine - if you really don't want to start *any* download before *all* the queries have finished. – Bergi Mar 17 '20 at 10:53

1 Answers1

2

I think it can be more readable to extract the inner function and then chain them together:

Promise.all(firstPromises)
  .then(transformToSecondPromises)
  .then(Promise.all)
  .then(values => {/* do later operation */})
  .catch(error => { debug(`Error in promises ${error}`) })

function transformToSecondPromises ([all, inventory, nearby]) {
  const fileKey1 = folderName + '/' + all.QueryExecutionId + '.csv';
  const fileName1 = all.QueryExecutionId + '.csv';
  const fileKey2 = folderName + '/' + inventory.QueryExecutionId + '.csv';
  const fileName2 = inventory.QueryExecutionId + '.csv';
  const fileKey3 = folderName + '/' + nearby.QueryExecutionId + '.csv';
  const fileName3 = nearby.QueryExecutionId + '.csv';
  return [
    s3Service.s3StreamDownload(bucketName, fileKey1, fileName1),
    s3Service.s3StreamDownload(bucketName, fileKey2, fileName2),
    s3Service.s3StreamDownload(bucketName, fileKey3, fileName3)
  ];
}
Zmen Hu
  • 795
  • 3
  • 12