强制JavaScript代码同步执行

3
我有一个异步函数(关闭套接字),必须在用户离开页面时执行。我尝试通过jQuery实现它:
$(window).unload(function() {
   socket.disconnect();
});

然而,这并不起作用,因为该函数是异步的,并且客户端在方法结束时立即离开页面,也就是说立即离开,断开套接字的请求没有执行。

我们可以提供一个回调函数,在socket.disconnect()函数执行结束时执行。也许这可以帮助解决问题...

有没有一种javascript的方法来解决这个问题?


1
有点棘手。你不能在服务器端检测到离开并从那里关闭它吗? - Mitya
已经尝试过了,我使用Node.JS,在客户端离开后2分钟内就会被检测到。这就是为什么我想尝试“客户端方式”,以提高效率。此外,Node有时会检测到虚假的断开连接,因此这可能是唯一正确的方法来真正检测到一个断开连接。 - Cydonia7
1
这是 socket.io 吗?通常情况下,可以通过在服务器端使用某种心跳来检测连接关闭来解决此问题。 - igorw
1
@igorw 对的,但是相对于客户端真正断开连接的时间,这会检测得非常晚。 - Cydonia7
不确定Socket.IO是如何工作的,但似乎这是没有意义的,因为在页面更改时套接字应该断开连接,连接不再打开。我编写了自己的WebSocket服务器,因此我有能力做到这一点。 - Sphvn
这似乎实际上是一个错误。你是如何处理你的服务器的? - Cydonia7
5个回答

3
我要冒昧地说,我认为这不可行——至少不是跨浏览器的。
有人建议可以通过onbeforeunload中断导航,但这在各个浏览器上的实现并不相同,而且即使可以中断,也不能(我相信)捕获用户正在前往的位置,以便在套接字关闭回调函数中将其转发。
一个不理想的妥协可能是使用onbeforeunload提示他们手动与服务器断开连接。许多人会这样做;那些无法这样做的人可以通过服务器端检测来捕获。

我确实喜欢这个想法,虽然这比没有好,但仍需要用户采取行动,我们不能假设每个人都会这样做。 - Cydonia7
我同意,我只是在说你可能没有太多其他选择。这是你的情况的限制,而不是我的答案 :) - Mitya
你说得对,如果我找不到更好的解决方案,我会把这个作为备选方案。谢谢你的帮助! - Cydonia7

1
window.onbeforeunload = function () {
    socket.disconnect();
    return 'This will disconnect all connections'; //Throws a prompt to user
};

更新:我没有看到这样做行不通。

有没有办法强制同步执行?

可能有。

var complete = false;

socket.on('disconnect', function () {
    complete = true;
});

while(!complete){
    //do nothing
}

在我的情况下,我做...
$.ajax({
    async: false    
});

这在使用onbeforeunload时运作良好。


我的问题是如何使它同步工作,因为我认为在 socket.io 中没有内置的同步方式来做到这一点。 - Cydonia7
是的,正如@Utkanos所说的那样...你无法知道他是点击了“确定”还是“取消”。 - Robin Maben
奇怪。complete = true 会被执行吗? - Robin Maben
旁边的console.log没有显示任何内容,所以我认为它不是。相当奇怪的。 - Cydonia7
1
我怀疑无限循环从未释放执行线程,以便回调函数能够完成其任务.. :( - Robin Maben
显示剩余7条评论

0

或许你可以尝试使用“beforeunload”事件代替“unload”事件,像这里所示,但我并不认为还有其他延迟窗口关闭的方法。


我之前已经尝试过beforeunload,但这并没有改变任何东西。 - Cydonia7

0

现在我的本地版本可以工作了,因为我已经降级到了socket.io 0.9.4。这确实是一个bug。但是现在它在我的主机(Heroku)上不起作用,因为它也安装了0.9.4版本(我进行了配置)。

我不知道该怎么解决这个问题,但是至少它在本地可以工作了...


0

看一下我之前提出的类似问题,结果发现在 socket.io 的版本 0.9.50.9.9 中存在一个 bug。

这里 是我的问题链接。希望能对你有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接