在 onbeforeunload 中等待承诺 [英] wait for promises in onbeforeunload

查看:39
本文介绍了在 onbeforeunload 中等待承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

window.onbeforeunload = function($http.get('http://someth.ing/update-state?page=unloaded').then(function(){//从未调用...从未发送...}}

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

我的想法是这样的:

window.onbeforeunload = function(){var 准备好 = 假;$http.get('http://someth.ing/update-state?page=unloaded').then(function(){准备好=真;}//除了这个,我看不到任何其他同步承诺的机会:while(!ready) angular.noop();//大问题:$http 现在调用服务器了吗?我们最终可以在这个方法中返回让浏览器退出"页面吗?}

RFC

解决方案

您有 2 个问题:

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

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

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

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

  • Worker 无法直接访问您的页面,您必须了解这一点,这意味着什么.例如 - 没有 window 对象,没有加载到您的库页面,工作人员的单独脚本,仅通过显式消息交换数据 - 仅举几例.

I want to send a $http.get if the page gets closed. Then I stumbold upon a problem where
promises can't get resolved because if this one last method returns, the page gets destroyed.

The following does not work because onbeforeunload can't resolve promises / does not wait for them:

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

}

I know, you can use default sync HTTP Methods but the question is generally how could we sync/wait for promises to resolve here.

My idea would be something like this:

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

解决方案

You have 2 problems:

  • You are using a callback (event handler) intended as "last-chance", this event handler, if browsers typically treat it in a special way, and doing any kind of long-running operations here is not intended.
  • Standard operation workflow will resume after this callback exits, meaning that any asynchronous operations are likely not going to be finished, especially if they are guaranteed to not be executed in the current tick (promises fall under this category, they will never be resolved synchronously by design).

So what to do to work within these limitations? You have a few options:

  • Avoid asynchronous code. You can do the http fetch before you get to this point, store the results and use them synchronously inside onbeforeunload.

  • Use ServiceWorker to continue doing work after page has been terminated. Again, I suggest creating, registring and activating worker before you get to handling onbeforeupload. During onbeforeupload handling - you want to postMessage to your worker, asking it to do some work for you. This option comes with 2 caveats:

  • ServiceWorker is not a released standard, it's still a draft, expect API changes, browser support issues and, indeed, potential scrapping of the API all together.

  • Worker has no direct access to your page, you have to be aware of that, what what it means. For example - no window object, no libraries loaded on your page, separate script for the worker, exchange of data via explicit messages only - to name a few.

这篇关于在 onbeforeunload 中等待承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆