在 service worker 中的 install 和 active 事件中事件对象会有 event.waitUntil() 方法,该对象方法可以存入一个 promise 对象,在这个 promise 没有返回期间,promise 内执行的操作不会触发 fetch 事件。我发现如果在 event.waitUntil()方法执行之前使用了 await 就会触发下列的错误
DOMException: Failed to execute 'waitUntil' on 'ExtendableEvent': The event handler is already finished and no extend lifetime promises are outstanding.
但是把 await 删除就不会触发这样的错误。为什么会这样设计?
self.addEventListener('activate', async (event) => {
console.log('service worker 被 激活')
const windowsClients = await self.clients.matchAll({
includeUncontrolled: true
})
event.waitUntil(Promise.all([enableNavigationPreload(), clients.claim()]))
})
在 Service Worker 中,event.waitUntil()
方法的设计是为了允许开发者延长事件的生命周期,直到传递给它的 Promise 被解决(resolved)。这主要用于 install
和 activate
事件,确保这些事件中的关键操作(如缓存文件、清理旧缓存等)完成后再让 Service Worker 进入下一个状态。
错误 DOMException: Failed to execute 'waitUntil' on 'ExtendableEvent': The event handler is already finished and no extend lifetime promises are outstanding.
发生的原因是,当你在事件处理函数中使用了 await
关键字时,它会暂停当前函数的执行,并等待 Promise 解决。然而,如果在 await
调用之后(即 Promise 解决之前)事件处理函数已经完成了执行(即函数体内的代码执行完毕,包括所有同步和已解决的异步代码),那么 ExtendableEvent
(install
和 activate
事件的对象类型)的生命周期就会被认为已经结束。
在你的示例中:
self.addEventListener('activate', async (event) => {
console.log('service worker 被 激活')
const windowsClients = await self.clients.matchAll({
includeUncontrolled: true
})
// 当到达这里时,如果 windowsClients 的 Promise 已经解决,但事件处理函数还未调用 event.waitUntil(),
// 则事件的生命周期可能已经结束,导致调用 event.waitUntil() 时抛出错误。
event.waitUntil(Promise.all([enableNavigationPreload(), clients.claim()]))
})
确保在事件处理函数结束之前调用 event.waitUntil()
,并且所有可能影响其生命周期的异步操作都应该在调用 event.waitUntil()
之前完成或包含在其 Promise 数组中。你可以通过调整代码顺序来实现这一点:
self.addEventListener('activate', async (event) => {
console.log('service worker 被 激活');
// 将所有需要等待的操作放入同一个 Promise.all 中
event.waitUntil(Promise.all([
self.clients.matchAll({ includeUncontrolled: true }), // 虽然这里的结果可能未直接使用,但可以避免错误
enableNavigationPreload(),
clients.claim()
]).then(() => {
// 这里可以处理匹配到的 windowsClients,但不影响 event.waitUntil 的行为
}));
});
注意,虽然在这个特定的例子中,self.clients.matchAll()
的结果可能并未在后续代码中被直接使用,但将其包含在 Promise.all
中可以避免因为等待其完成而导致的事件生命周期提前结束的问题。同时,这也确保了所有必要的异步操作都在 event.waitUntil()
的控制之下。
当页面中存在多个css动画,css动画过于复杂,或者电脑性能不足时,都有可能导致动画卡顿。对css动画的优化方法都有哪些?
本文向大家介绍python中类的一些方法分析,包括了python中类的一些方法分析的使用技巧和注意事项,需要的朋友参考一下 本文实例分析了python中类的一些方法,分享给大家供大家参考。具体分析如下: 先来看看下面这段代码: 本文实例运行环境为Python2.7.6 运行结果如下: in Provider.action 在Super类中定义delegate()方法,delegate中调用sel
TS中在抽象类中是否可以写一些已经实现的方法? 这个代码是一个抽象类BaseEdge,在里面有方法updateCache,这个是已经实现了的。也就是说抽象类中可以有已经实现好的方法是吗?
本文向大家介绍一些基础的js 方法?相关面试题,主要包含被问及一些基础的js 方法?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: Function.prototype.a = 1; Object.prototype.b = 2; function A() {} var a = new A(); console.log(a.a, a.b); // undefined, 2 console.
https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_flow_lay... 上面的文章写到: 1.常规流中:块级盒子是在块格式上下文(BFC)中的,而内联盒子是在内联格式上下文中的(IFC); 2.块格式上下文(BFC)中,盒子是垂直排列的; 3.内联格式上下文(IFC)中,盒子水平排列; 那么问题来了: 例子:通过display:flow-r
我有一个关于JMS和Spring集成的问题。 我有3个队列,让我们称它们为QUEUE_SOURCE、QUEUE_TARGET和QUEUE_ERROR。DefaultMessageListenerContainer用于从队列源读取消息。 我已经为这些队列配置了JMS事务管理器。 当我从QUEUE_源读取消息,但将消息发布到QUEUE_目标时出错时,我可以看到在抛出异常之前,消息会重试几次,从而触发回