I try to make a simple website which send some push notification. Here is a part of code :
function getSubscribers() {
var subscribers = {};
try {
var subscribersRaw = fs.readFileSync(SUBSCRIBERS_PATH);
subscribers = JSON.parse(subscribersRaw);
} catch (err) {}
return subscribers;
}
function setSubscribers(data) {
fs.writeFileSync(SUBSCRIBERS_PATH, data);
}
function sendNotifications(req, res) {
var message = "message";
var icon = "icon.png"
var subscribers = getSubscribers();
var subscriber_deleted = 0;
for (var subid in subscribers) {
const subscription = subscribers[subid];
const payload = {
message: message,
icon : icon
};
const options = {
TTL: 3600
};
webPush.sendNotification(subscription, JSON.stringify(payload), options)
.then(function() {})
.catch(function(error) {
console.log(error);
if (error.statusCode === 410) {
delete subscribers[subid];
subscriber_deleted = 1;
}
});
}
if(subscriber_deleted==1)
{
setSubscribers(JSON.stringify(subscribers));
}
}
The main problem is webPush.sendNotification in sendNotifications function. webPush.sendNotification return a promise which return the same object if it succeed or failed. The main difference is the error code inside the object returned which is similar to http code. If the code return is equal to 410, it is necessary to not resend the notification next time.
This part is useless because of the async propriety of webPush.sendNotification
if(subscriber_deleted==1)
{
setSubscribers(JSON.stringify(subscribers));
}
I tried to use Promise.all especially 'finally' function without success.
How properly handle this ?
Ok,
You have a list of suscriber in a file. You start by loading it. Then you send notifications to all suscribers asynchronously. If a suscriber send a code 411, you remove that suscriber from list, both in memory and in file.
Is that all right?
Using promise.all is the good way, so you have to build an array of functions returning a promise, to feed promise.all. then you can await it to check properly if some call fails meaning you need to rewrite suscriber list on disk.
So:
await promise.all(suscribers.keys().map(notify))
Since you return the result of catch, reject from sendNotification won't stop tha await of promise.all