angular checkForUpdate在强制重新加载后无法工作,

o4tp2gmn  于 4个月前  发布在  Angular
关注(0)|答案(9)|浏览(69)

哪个@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

还有其他信息吗?

  • 无响应*
jljoyd4f

jljoyd4f1#

相同的错误,它从未解决。

mftmpeh8

mftmpeh82#

问题是,在强制重新加载后,页面与ServiceWorker的状态处于一种奇怪的状态:
浏览器确实支持ServiceWorkers(因此SwUpdate#isEnabledtrue),并且有一个活动的SW注册(即(await navigator.serviceWorker.ready).active(await navigator.serviceWorker.getRegistration()).active都指向一个已激活的ServiceWorker),但页面不受ServiceWorker控制(因此navigator.serviceWorker.controllernull)。
然而,在我所知的范围内,没有可靠的方法来区分这两种状态。

pinkon5k

pinkon5k3#

@gkalpak,所以基本上执行checkForUpdate时,执行navigator.serviceWorker.controller == null是没有意义的?

p3rjfoxz

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: ***@***.***>

mu0hgdu0

mu0hgdu05#

@gkalpak,所以基本上在navigator.serviceWorker.controller == null时执行checkForUpdate是没有意义的,对吗?
为什么不在这种情况下拒绝这个承诺呢?
问题不在于navigator.serviceWorker.controller === null,而是它会保持null。再说一次,我不知道如何可靠地区分强制重新加载示例(其中有一个活动的SW,但它不会控制页面)和ServiceWorker目前正在安装/激活的状态,并且很快就会开始控制页面(因此navigator.serviceWorker.controller将很快停止成为null)。

5hcedyr0

5hcedyr06#

在我的案例中,navigator.serviceWorker.controller 永远不会得到一个示例(也许因为我正在使用registerImmediately?),所以在这种情况下,我认为window.location.reload();可以解决这个问题(通过正常重新加载应用程序),但我认为这仅适用于第一次应用程序加载,并且您正在显示一个旋转器(这样用户就不会看到页面两次显示)。

这似乎是有意为之,因为它发生在Chrome和Firefox上...*
关于这个问题的一个问题是,有什么可以在示例化后将其更改为null的东西吗?

qyuhtwio

qyuhtwio7#

我不知道任何事情,但我不确定。

amrnrhlw

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不应该运行,以及如何处理更新。

csbfibhn

csbfibhn9#

看起来在强制刷新后(仅在按下F5后),VERSION_DETECTED事件永远不会被发出。

相关问题