将Promise作为if条件判断时出现逻辑错误的问题求助
问题描述
本人不擅长JS Promise与异步编程,现遇到相关问题。简化代码如下:
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; }); }
逻辑很明确:isClientFocused函数会根据情况返回true或false,我想将该值作为事件监听器中if语句的判断条件。
我确认isClientFocused函数本身能正常工作,每次都能返回预期结果,但将其用于if条件判断时,总是会输出“Don't need to show a notification.”。
我猜测这只是实现问题,但目前有些困惑,恳请各位提供帮助。
问题分析与解决
你的核心问题是:isClientFocused()返回的不是直接的布尔值,而是一个Promise对象。在JavaScript中,所有对象在布尔判断里都会被视为true,所以你的if(isClientFocused())条件永远成立,导致每次都执行return分支。
下面提供两种简洁的修复方案:
方案1:使用async/await(更直观)
将push事件的回调改为async函数,通过await获取Promise的实际返回值:
self.addEventListener('push', async (event) => { const data = event.data ? event.data.json() : {} // 等待Promise解析出真实的布尔值 const clientIsFocused = await isClientFocused(); if (clientIsFocused) { 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; }); }
方案2:使用Promise链式调用
如果不想用async/await,可以把逻辑嵌套在isClientFocused()的then回调里,同时要把整个流程放到event.waitUntil()中,确保Service Worker不会提前终止:
self.addEventListener('push', (event) => { const data = event.data ? event.data.json() : {} event.waitUntil( isClientFocused().then(clientIsFocused => { if (clientIsFocused) { console.log('Don\'t need to show a notification.'); return; } // 返回通知Promise,让waitUntil等待其完成 return 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; }); }
内容的提问来源于stack exchange,提问作者Tartempion34
相关产品推荐
相关产品推荐

