1

I am trying to resolve the array of promises together. Not sure how to do it. Let me share the pseudo code for it.

async function sendNotification(user, notificationInfo) {
    const options = {
        method: 'POST',
        url: 'http://xx.xx.xx:3000/notification/send',
        headers:
    { 'Content-Type': 'application/json' },
        body:
    { notificationInfo, user },
        json: true,
    };
    console.log('sent');

     return rp(options);
}

I have wrapped the sendNotification method in another method which returns the promise of rp(request-promise) module.

Next i am pushing this sendNotification method in array of promise , something like this

const notificationWorker = [];
for (const key3 in notificationObject) {
                          if(notificationObject[key3].users.length > 0) {
                            notificationWorker.push(sendNotification(notificationObject[key3].users, notificationObject[key3].payload));  // problem is notification are going as soon as i am pushing in notificationWorker array.
                          }
                }
    // task 1 - send all notifications
const result = await Promise.all(notificationWorker); // resolving all notification promises together
    // task 2 - update values in db , after sending all notifications
    const result2 = await Promise.all(updateWorker); // update some values in db

In above code , my problem is notifications are going as soon as i am pushing it in notificationWorker array. I want all notifications to go together, when i run await Promise.all(notificationWorker)

Not sure , how to achieve what i am trying?

NeiL
  • 791
  • 8
  • 35
  • Your code looks fine to me. Can you clarify what you mean by "my problem is notifications are going as soon as i am pushing it in notificationWorker array. I want all notifications to go together..."? – Arun Kumar Mohan Feb 14 '21 at 07:33
  • 1
    What is the real difference that you are hoping for? Nothing *exactly* goes at the same time, but all code will immediately run until a true asyncronous point in your code is hit. Why does it matter in this case, because the difference should be minimal? – Evert Feb 14 '21 at 07:34
  • @ArunKumarMohan I am trying to send notification together with Promise.all(notificationWorker), before that in for loop, i am simply pushing it in notificationWorker in array. – NeiL Feb 14 '21 at 07:36
  • @Evert have added more explanation . So , in task 1 - sending all notifications, task 2 - update some values in db after sending notifications. want it to be sequential – NeiL Feb 14 '21 at 07:38
  • 1
    > I am trying to send notification together with Promise.all(notificationWorker)... That's not how it works. `Promise.all` returns a promise which resolves when all the input promises resolve. – Arun Kumar Mohan Feb 14 '21 at 07:41
  • 3
    You may be confused about `Promise.all()`. It doesn't send any of your messages. All, it does is track the promises that your function that initiates the message sending returned. YOU initiated sending the messages when you put the promise in the array. That's when the messages are sent. This is not something `Promise.all()` has any role in. It just tracks the promises you got back from initiating the message send. – jfriend00 Feb 14 '21 at 07:41
  • @jfriend00 Yes, understood now , is there a way to achieve what i am trying to do. – NeiL Feb 14 '21 at 07:43
  • 1
    what does `rp(options)` do? – Alan Omar Feb 14 '21 at 07:44
  • @NeiL if you want to make some changes in the db after sending, do this after `await Promise.all()` – Evert Feb 14 '21 at 07:45
  • @AlanOmar It sends post request to the given url which is send notification to user in my case. – NeiL Feb 14 '21 at 07:46
  • Well, there is no such thing as sending multiple notifications at exactly the same time. That's just physically impossible There's only one network link the messages are doing to go out on anyway so one is always going to be before the other. You can get everything ready to go and then send the first one and then send the second one and that's the best you can do. One has to go before the other. If the notifications are going to the same source, then you could somehow bundle the data from both into the same notification so you only send one notification that contains both pieces of data. – jfriend00 Feb 14 '21 at 08:01
  • I agree with Alan Omar: we need to see the implementation of `rp`. If it awaits some promise to resolve, then there is your issue. – trincot Feb 14 '21 at 10:13

1 Answers1

0

I understood the question partially , but then i feel this is difference between nodejs working concurrently and we trying to achieve parallelism , isn't that so.

Nodejs just switching between the tasks by , and not actually parallely doing it.Child Process might help you in that case.

So for eg. if you go through a snippet

function done(i){
    try{
      return new Promise((resolve,reject)=>{
        console.log(i);
        resolve("resolved " + i + "th promise");
      })
    }catch(e){
      return null;
    }
}


let promises = [];
for(let i=0;i < 100000; i++){
  promises.push(done(i));
}

So console starts even when you dont call Promise.all right ? this was your question but infact Promise.all should not suffice your thing , should go by spwaning child processes to achieve parallelism to some extent.

The point i am trying to make it you are potraying the question to do something like first generate array of promises and start all of them once when Promise.all is called but in my opinion Promise.all also will be running concurrently not giving you what you want to achieve.

Something like this - https://htayyar.medium.com/multi-threading-in-javascript-with-paralleljs-10e1f7a1cf32 || How to create threads in nodejs

Though most of these cases show up when we need to do a cpu intensive task etc but here we can achieve something called map reduce to distribute you array of users in parts and start that array to loop and send notifications.

All of the solutions, i am presenting is to achieve some kind of parallelism but i dont think sending array of huge amount of users would ever be done easily (with less resources - instance config etc) at same instant

good boy
  • 11
  • 3