如何确保在页面卸载之前始终调用代码

Posted

技术标签:

【中文标题】如何确保在页面卸载之前始终调用代码【英文标题】:How to ensure code is always called before page unload 【发布时间】:2012-08-07 19:01:24 【问题描述】:

通常这并不重要,甚至可能对我的情况也不太重要,但我想知道是否有合理的方法来实现这一点。

我的页面会自动打开一个 Web 套接字连接。为了成为更好的客户端,我希望客户端自行清理并在页面卸载之前关闭 websocket。

我希望浏览器在页面卸载时有远见为我调用close(),但如果没有,我如何利用onbeforeunload消息(或类似消息)来做一些“最终清理”(与 C 中的 atexit() 不同)?

假设我有一些系统,我希望我的客户出于某种原因向我的 websocket 服务器发送“退出”消息。

我现在可以这样做了:

$(window).on('beforeunload', function () 
    websocket.close(); // websocket is a WebSocket
);

但假设close() 实际上是一个异步调用(是吗?),我想确保 socket.onclose 回调在实际卸载页面之前触发!这可以做到吗?

【问题讨论】:

如果你控制了服务端,你可以要求每n分钟一次客户端心跳——如果服务端没有收到心跳,那么服务端关闭套接字以清理任何孤立的客户端套接字浏览器可能已经闲置了。 @jfriend00 这听起来像是处理这个问题的绝佳方法。看来我在onbeforeunload 中的close() 也在起作用。 我认为你不能指望close() 在所有浏览器中都能正常工作,但在那里尝试并没有什么坏处。心跳涵盖所有情况,甚至包括通知您关闭窗口时的浏览器错误。 【参考方案1】:

没有确保异步调用在现代浏览器中完全执行的可靠方法。旧版本可能会被 while 循环阻止,但当前的浏览器会终止任何进程并继续。原因是他们希望用户体验快速,你阻止他们对他们有害。

【讨论】:

是的,做一个繁忙的循环来阻止卸载不是一个合适的解决方案。 @StevenLu 它曾经是唯一的解决方案。 :)【参考方案2】:
window.onunload=function()
//your code here

我想我们确实有这个。

【讨论】:

这对于非异步的东西应该足够了,但要验证我的 websocket.onclose 已经运行(这是异步的)它还不够。也许没有解决办法。

以上是关于如何确保在页面卸载之前始终调用代码的主要内容,如果未能解决你的问题,请参考以下文章

加载页面时如何始终调用 onClick?错误:超过最大更新深度 [重复]

如何确保在从 Mongoose 中的函数返回之前执行异步调用?

在页面卸载之前显示加载 GIF

怎样确保页面中的js代码一定是在DOM结构生成之后再调用

如何确保物化视图始终是最新的?

如何确保 UWP 应用在启动时始终全屏显示?