I’m quite bad with JS promises and async and I face a problem about it.
First things first the simplified code:
self.addEventListener('push', (event) => {
const data = event.data ? event.data.json() : {}
if (isClientFocused()) {
console.log('Don't need to show a notification.');
return;
}
event.waitUntil(
self.registration.showNotification(data.title, data)
)
});
function isClientFocused() {
return self.clients.matchAll({
type: 'window',
includeUncontrolled: true
})
.then((windowClients) => {
let clientIsFocused = false;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.focused) {
clientIsFocused = true;
break;
}
}
return clientIsFocused;
});
}
The concept is quite straight forward: my function isClientFocused
return true
or false
depending on the situation and I want to use this value as a condition in my if in my event listener.
I precise that isClientFocused function works well and everytime return the result as expected, but when used in the if condition, it always log Don't neet to show notification.
I guess it’s just an implementation problem but I’m a bit lost right now.
Thanks in advance for your help.
2
Answers
Just add async/await because isClientFocused() returns a promise and it’s truthy and condition is always true. With the resolved value with
await
you get a proper logic.Also you should call
event.waitUntil
immediately (sync):I suggest to refactor isClientFocused() with async/await and use async/await as much as possible to avoid
then()
. Also you could useArray::some()
instead of your loop.In my experience
async/await
leads to less bugs and more readable and maintainable when async/await is learned.It’s just amazing when I refactor a buggy
then()
code toasync/await
the bugs disappeared automatically.Cause of this, isClientFocused function is a Promise, when you call it, you have to wait for complete this function.
The code should look like this;
Note : Promise gives an output similar to this if you do not wait for a function to run ;