在注册服务工作者之前尝试运行获取功能。

纳什

我正在尝试运行获取功能,该功能将从服务器上获取一些值。但是由于某种原因,服务工作者的注册会首先触发,并且未定义的“ app_key”会引发异常。看来这是我不知道如何解决的比赛条件。

我不确定如何将值分配给变量,以确保其他函数可以看到它们。任何建议,将不胜感激。

project_url = window.location.hostname;

var vapi_key;
var app_key;
var pushSub;
var end_point = "https://" + project_url + "/push/subscribe/create";

(() =>  {
    return fetch ("https://" + project_url + "/push/get_public_key"
    ).then((response) => {
        return response.json();
    })
    .then((responseJSON) => {
        vapi_key = responseJSON;
        urlBase64ToUint8Array(vapi_key);
        console.log("VAPI_KEY: ", vapi_key);
        console.log("APP_KEY: ", app_key)
    }).catch((err) => {
        console.log('Fetch Error : ', err);
    });
})();


(() => {
    return new Promise((resolve, reject) => {
        const permissionResult = Notification.requestPermission((result) => {
            resolve(result);
        });

        if (permissionResult) {
            permissionResult.then(resolve, reject);
        }
    })
        .then((permissionResult) => {
            if (permissionResult !== 'granted') {
                throw new Error('We weren\'t granted permission.');
            }
        });
})();

(() => {
    if ('serviceWorker' in navigator && 'PushManager' in window) {
        navigator.serviceWorker.register('/sw_bundle.js')
            .then((registration) => {
                let subscribeOptions = {
                    userVisibleOnly: true,
                    applicationServerKey: app_key,
                };

                return registration.pushManager.subscribe(subscribeOptions);
            })
            .then((pushSubscription) => {
                console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
                const subscriptionObject = {
                    endpoint: pushSubscription.endpoint,
                    keys: {
                        p256dh: pushSubscription.keys['p256dh'],
                        auth: pushSubscription.keys['auth']
                    }
                };
                sendSubscriptionToBackEnd(subscriptionObject);
                return pushSubscription;
            });
    } else {
        console.warn('Push messaging is not supported');
    }
})();

function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');
    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);
    for (var i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    app_key = outputArray;
}
FK82

我不确定为什么您希望这样做有效。特别是为什么要使用IIFE来创建承诺。无论如何,如果您希望将一个承诺链接到另一个承诺,则需要通过在.then对第一个承诺调用中创建第二个承诺来使其明确这是一个例子:

const createPromiseA = () => new Promise((resolve) => {
window.setTimeout(() => { console.log('promiseA'); resolve(); }, 2000);
});

const createPromiseB = () => new Promise((resolve) => {
window.setTimeout(() => { console.log('promiseB'); resolve(); }, 3000);
});

createPromiseA().then(createPromiseB);

对于您的情况,您需要执行以下操作:

const fetchKeys = () => fetch ("https://" + project_url + "/push/get_public_key"
    ).then((response) => {
        return response.json();
    })
    .then((responseJSON) => {
        vapi_key = responseJSON;
        urlBase64ToUint8Array(vapi_key);
        console.log("VAPI_KEY: ", vapi_key);
        console.log("APP_KEY: ", app_key)
    }).catch((err) => {
        console.log('Fetch Error : ', err);
    });

const registerWorker = () => {
    if ('serviceWorker' in navigator && 'PushManager' in window) {
        navigator.serviceWorker.register('/sw_bundle.js')
            .then((registration) => {
                let subscribeOptions = {
                    userVisibleOnly: true,
                    applicationServerKey: app_key,
                };

                return registration.pushManager.subscribe(subscribeOptions);
            })
            .then((pushSubscription) => {
                console.log('Received PushSubscription: ', JSON.stringify(pushSubscription));
                const subscriptionObject = {
                    endpoint: pushSubscription.endpoint,
                    keys: {
                        p256dh: pushSubscription.keys['p256dh'],
                        auth: pushSubscription.keys['auth']
                    }
                };
                sendSubscriptionToBackEnd(subscriptionObject);
                return pushSubscription;
            });
    } else {
        return Promise.reject('Push messaging is not supported');
    }
};

// …

fetchKeys().then(registerWorker)
.then(() => { console.log('(!) Success!'); });

注意:使用IIFE的一种更好的方法是将整个脚本包装在一个函数中并执行它。这样会将变量绑定到函数的局部作用域,而不公开它们。即做类似的事情:

(() => {
    project_url = window.location.hostname;

    var vapi_key;
    var app_key;
    var pushSub;
    var end_point = "https://" + project_url + "/push/subscribe/create";

    // ...

    const fetchKeys = () => { ... } ;
    const registerWorker = () => { ... } ;

    // ...

    fetchKeys().then(registerWorker)
    .then(() => { console.log('(!) Success!'); });

})();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章