我无法捕获由服务人员的消息事件引发的异常。
客户端使用以下代码在SW上执行命令:
import { messageSW } from "workbox-window";
// .. code for Workbox initialization/registration omitted
messageSW(registration?.active, { type: "SYNC" })
.then((results) => {
console.log("done");
})
.catch((e) => {
console.error(e);
});在SW (sw.js)方面,我有以下代码:
self.addEventListener("message", async (event) => {
if (requestType === "SYNC") {
event.ports[0].postMessage(await longRunningTask());
}
});只要SW不抛出任何异常,此解决方案就能正常工作。这意味着在执行SW上长期运行的进程之后,客户端将打印"done“消息。如果抛出异常,则不会返回..。
我通过以下操作成功地解决了这个问题:
self.addEventListener("message", async (event) => {
if (requestType === "SYNC") {
try {
event.ports[0].postMessage(await longRunningTask());
} catch (error) {
event.ports[0].postMessage(error);
}
}
});在这种情况下-结果总是返回的,不管如何,"done“都会被打印出来,但是:
如何从服务工作者( it
发布于 2022-05-02 10:36:44
下面是我自己的解决方案,我最终使用了:
关于服务工作者的帮助者方法:
async function replyToSenderAsync(event, task) {
let isCanReply = event.ports && event.ports.length >= 0;
try {
const result = await task();
if (isCanReply) {
event.ports[0].postMessage({ error: null, message: result });
}
} catch (error) {
if (isCanReply) {
event.ports[0].postMessage({ error: error, message: null });
}
}
}当异常被捕获时,我们设置error属性。用作:
self.addEventListener("message", async (event) => {
const requestType = event?.data?.type;
if (requestType === "QUEUE_CLEAR") {
await replyToSenderAsync(event, async () => await clearQueueAsync());
}
});在客户端请求包装:
function sendMessageToSWAsync(targetSW, messageType, message) {
return new Promise(function (resolve, reject) {
if (
!isServiceWorkerSupported.value ||
!isServiceWorkerRegistered.value ||
!targetSW
) {
reject(new Error("Unable to send the message to a service worker"));
}
try {
messageSW(targetSW, { type: messageType, message: message })
.then((messageResponse) => {
if (!messageResponse) {
reject(new Error("Service worker responsed with empty response"));
} else {
if (messageResponse.error) {
reject(messageResponse.error);
} else {
resolve(messageResponse.message);
}
}
})
.catch((messageError) => {
reject(messageError);
});
} catch (error) {
reject(error);
}
});
}这里的神奇之处是读取error属性,如果是这样的话,则拒绝允诺(因此会引发异常)。用作
try {
let response = await sendMessageToSWAsync(registration?.active, "QUEUE_GET_ALL");
}
catch(error) {
}
sendMessageToSWAsync(registration?.active, "QUEUE_GET_ALL")
.then((response) => {})
.catch((error) => {})https://stackoverflow.com/questions/72072605
复制相似问题