等待 onbeforeunload 中的承诺

问题描述 投票:0回答:1

如果页面关闭,我想发送 $http.get。然后我偶然发现了一个问题
承诺无法得到解决,因为如果最后一个方法返回,页面就会被破坏。

以下内容不起作用,因为 onbeforeunload 无法解析承诺/不等待它们:

window.onbeforeunload = function(
    $http.get('http://someth.ing/update-state?page=unloaded').then(function(){
        // never called... never sent...
    }

}

我知道,您可以使用默认的同步 HTTP 方法,但问题通常是我们如何同步/等待承诺在这里解决。

我的想法是这样的:

window.onbeforeunload = function(){
    var ready = false;

    $http.get('http://someth.ing/update-state?page=unloaded').then(function(){
         ready=true;
    }

    // I don't see any other opportunity to sync a promise here than this:
    while(!ready) angular.noop();
    // big question: did $http call the server now? Can we finally return in this method to let the browser 'exit' the page?
}

RFC

javascript angularjs synchronization angular-promise onbeforeunload
1个回答
10
投票

您有 2 个问题:

  • 您正在使用回调(事件处理程序)作为“最后机会”,如果浏览器通常以特殊方式对待它,则此事件处理程序,并且不打算在此处执行任何类型的长时间运行操作。
  • 此回调退出后,标准操作工作流程将恢复,这意味着任何异步操作都可能不会完成,特别是如果保证它们不会在当前tick中执行(promise属于此类,它们永远不会被同步解决)按设计)。

那么如何才能在这些限制内工作呢?您有几个选择:

  • 避免异步代码。您可以在到达此点之前执行 http fetch,存储结果并在 onbeforeunload 中同步使用它们。

  • 使用 ServiceWorker 在页面终止后继续执行工作。再次,我建议您在处理 onbeforeupload 之前创建、注册并激活工作线程。在 onbeforeupload 处理期间 - 您想要

    postMessage
    给您的工作人员,要求它为您做一些工作。此选项有 2 个注意事项:

    • ServiceWorker 不是一个已发布的标准,它仍然是一个草案,预计会出现 API 更改、浏览器支持问题,甚至可能会废弃 API。
    • Worker 无法直接访问您的页面,您必须了解这一点,这意味着什么。例如 - 没有 window 对象,页面上没有加载任何库,为工作人员提供单独的脚本,仅通过显式消息交换数据 - 仅举几例。
© www.soinside.com 2019 - 2024. All rights reserved.