我正在尝试运行获取功能,该功能将从服务器上获取一些值。但是由于某种原因,服务工作者的注册会首先触发,并且未定义的“ 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;
}
我不确定为什么您希望这样做有效。特别是为什么要使用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] 删除。
我来说两句