哪个@angular/*包是bug的来源?
service-worker
这是个回归吗?
不是
描述
这个问题跟#44044有关,后者已经关闭。
配置:
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: environment.minimized && environment.environment === 'staging',
registrationStrategy: 'registerWhenStable:120000'
})
更新检查在初始化时执行:
{
provide: APP_INITIALIZER,
useFactory: (service: ServiceWorkerService) => () => service.check$(),
deps: [ServiceWorkerService],
multi: true
}
ServiceWorkerService:
public check$(): Observable<unknown> {
if (this.swUpdate.isEnabled) {
return of(undefined).pipe(
tap(() => this.info('Start check for update')),
concatMap(() => this.swUpdate.checkForUpdate()),
tap((value) => {
this.info('Update available', value);
if (value) {
this.growlService.showInfo('Application update is installed. Page will reload in 5 seconds.', 'Update');
}
}),
concatMap((value) => (value ? of(value).pipe(delay(5000)) : of(value))),
tap((value) => {
if (value) {
this.beforeUnloadService.skip(() => {
reload();
});
}
}),
concatMap((value) => (value ? NEVER : of(undefined)))
);
} else {
return of(false);
}
}
可以在我们的测试服务器上重现,如有需要,我可以私下提供链接。
请提供一个重现bug的最小链接
- 无响应*
请提供您看到的异常或错误
There are no errors, `this.swUpdate.checkForUpdate()` never resolves.
请提供您发现此bug的环境(运行ng version
)
Angular CLI: 13.0.4
Node: 14.18.0
Package Manager: yarn 1.22.5
OS: win32 x64
Angular: 13.0.3
... animations, cdk, common, compiler, compiler-cli, core
... elements, forms, language-service, material
... platform-browser, platform-browser-dynamic, router
... service-worker
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1300.1
@angular-devkit/build-angular 13.0.4
@angular-devkit/core 13.0.4
@angular-devkit/schematics 13.0.4
@angular/cli 13.0.4
@schematics/angular 13.0.4
rxjs 7.4.0
typescript 4.4.4
还有其他信息吗?
- 无响应*
9条答案
按热度按时间jljoyd4f1#
相同的错误,它从未解决。
mftmpeh82#
问题是,在强制重新加载后,页面与ServiceWorker的状态处于一种奇怪的状态:
浏览器确实支持ServiceWorkers(因此
SwUpdate#isEnabled
是true
),并且有一个活动的SW注册(即(await navigator.serviceWorker.ready).active
和(await navigator.serviceWorker.getRegistration()).active
都指向一个已激活的ServiceWorker),但页面不受ServiceWorker控制(因此navigator.serviceWorker.controller
是null
)。然而,在我所知的范围内,没有可靠的方法来区分这两种状态。
pinkon5k3#
@gkalpak,所以基本上执行
checkForUpdate
时,执行navigator.serviceWorker.controller == null
是没有意义的?p3rjfoxz4#
在这种情况下,为什么不拒绝这个承诺呢? wdniu sob., 19.03.2022 o 21:09 Alexander Turtsevich < ***@***.***> napisał(a):...
@gkalpak < https://github.com/gkalpak >,所以基本上当 navigator.serviceWorker.controller == null 时执行 checkForUpdate 没有意义? — 直接回复此电子邮件,查看GitHub <#44402 (comment)>,或取消订阅 < https://github.com/notifications/unsubscribe-auth/AFKBQQMFWY26A23Z2CYYLNLVAYYADANCNFSM5JTT7VHQ >。使用GitHub Mobile for iOS < https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 > 或Android < https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub > 在外出时对通知进行分类。您收到此消息是因为您进行了评论。Message ID: ***@***.***>
mu0hgdu05#
@gkalpak,所以基本上在
navigator.serviceWorker.controller == null
时执行checkForUpdate
是没有意义的,对吗?为什么不在这种情况下拒绝这个承诺呢?
问题不在于
navigator.serviceWorker.controller === null
,而是它会保持null
。再说一次,我不知道如何可靠地区分强制重新加载示例(其中有一个活动的SW,但它不会控制页面)和ServiceWorker目前正在安装/激活的状态,并且很快就会开始控制页面(因此navigator.serviceWorker.controller
将很快停止成为null
)。5hcedyr06#
在我的案例中,
navigator.serviceWorker.controller
永远不会得到一个示例(也许因为我正在使用registerImmediately
?),所以在这种情况下,我认为window.location.reload();
可以解决这个问题(通过正常重新加载应用程序),但我认为这仅适用于第一次应用程序加载,并且您正在显示一个旋转器(这样用户就不会看到页面两次显示)。这似乎是有意为之,因为它发生在Chrome和Firefox上...*
关于这个问题的一个问题是,有什么可以在示例化后将其更改为null的东西吗?
qyuhtwio7#
我不知道任何事情,但我不确定。
amrnrhlw8#
我真的很惊讶这种行为(https://web.dev/service-worker-lifecycle/#shift-reload)是有意为之的!对我们来说,这只会带来麻烦。首先,它看起来像在这里提到的重新注册Service Worker的解决方法:https://stackoverflow.com/questions/51597231/register-service-worker-after-hard-refresh 将会是解决方案,但现在有了这个解决方法,当执行SHIFT-F5时,情况如下:
无更新可用
checkForUpdate()
返回的promise解析为false。这是可以接受的。有更新可用
一旦服务器上出现可用更新,对
checkForUpdate()
的第一调用不会触发VERSION_DETECTED事件。当然,这可能是解决方法的一个副作用,但我真的很想了解为什么在执行SHIFT-F5时Service Worker不应该运行,以及如何处理更新。
csbfibhn9#
看起来在强制刷新后(仅在按下F5后),VERSION_DETECTED事件永远不会被发出。