You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 15:40:10