在onbeforeunload等待承诺

noX*_*oXi 12 javascript synchronization onbeforeunload angularjs angular-promise

如果页面关闭,我想发送$ http.get.然后我找不到promises无法解决的问题,
因为如果最后一个方法返回,页面就会被销毁.

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

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

}
Run Code Online (Sandbox Code Playgroud)

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

我的想法是这样的:

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?
}
Run Code Online (Sandbox Code Playgroud)

RFC

tra*_*nik 6

你有两个问题:

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

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

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

  • 页面终止后,使用ServiceWorker继续工作。同样,我建议在处理 onbeforeupload 之前创建、注册和激活工作线程。在 onbeforeupload 处理期间 - 您想对postMessage您的工人,要求它为您做一些工作。此选项有两个注意事项:

  • ServiceWorker 不是一个已发布的标准,它仍然是一个草案,预计 API 更改、浏览器支持问题以及实际上可能会一起废弃 API。

  • Worker 无法直接访问您的页面,您必须了解它的含义。例如 - 没有窗口对象,没有加载到您的页面上的库,单独的工作脚本,仅通过显式消息交换数据 - 仅举几例。