【问题标题】:Force a javascript code to be synchronous强制 javascript 代码同步
【发布时间】:2012-07-29 00:12:37
【问题描述】:

我有一个异步函数(关闭套接字),当用户离开页面时我必须执行它。我试图通过 jQuery 来做到这一点:

$(window).unload(function() {
   socket.disconnect();
});

但是,这不起作用,因为该函数是异步的,并且客户端在到达方法末尾时立即离开页面,也就是说立即并且不执行断开套接字的请求。

我们可以提供在socket.disconnect() 函数执行结束时执行的回调。也许这会有所帮助...

javascript有没有办法解决这个问题?

【问题讨论】:

  • 棘手。难道你不能检测到服务器端的离开并从那里关闭它吗?
  • 已经试过了,我用的是Node.JS,在客户端离开2分钟后检测到。这就是为什么我想尝试“客户方式”,以提高效率。此外,Node 有时会检测到错误的断开连接,因此这可能是真正检测到断开连接的唯一正确方法。
  • 这是socket.io吗?仅供参考,通常这个问题是通过使用某种心跳来检测服务器端的连接关闭来解决的。
  • @igorw 是的,但与客户端真正断开连接的时间相比,这检测到它真的很晚。
  • 不确定 Socket.IO 是如何工作的,但这似乎毫无意义,套接字应该在页面更改时断开连接,连接不再打开。我编写了自己的 WebSocket 服务器,所以我有能力做到这一点。

标签: javascript websocket


【解决方案1】:

看看我有一个类似的问题,原来socket.io0.9.50.9.9 有一个错误。

Here's 我的问题的链接。希望这会有所帮助。

【讨论】:

    【解决方案2】:

    它现在可以在我的本地版本中使用,因为我已降级到 socket.io 0.9.4。这确实是一个错误。现在它在我的主机(Heroku)上也不能工作,它也有 0.9.4 版本(我配置了它)。

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

    【讨论】:

      【解决方案3】:
      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 中没有内置的方式来同步地做到这一点。
      • @Skydreamer:调整socket.io 的代码是一种选择吗? :P
      • 我想是这样,但我不知道是否可以在运行时修改它(因为我使用 Heroku,它会按原样安装 Socket.IO)
      • @Skydreamer:另一种丑陋的方式是在回调中使用 return 语句。这样就有一个提示,它应该足以让disconnect() 执行。
      • 我怀疑无限循环永远不会为回调释放执行线程来完成它的工作.. :(
      【解决方案4】:

      我会直言不讳地说我不相信这是可行的——至少不能跨浏览器。

      正如有人建议的那样,您可以通过onbeforeunload 中断导航,但这不是在同一个跨浏览器中实现的,即使您可以中断它,您也无法(我相信)捕获用户的去向,例如也就是说,在你的套接字关闭回调中,你可以转发它们。

      一个不理想的妥协可能是使用onbeforeunload 至少提示他们手动断开与服务器的连接。许多人会;那些没有的你可以通过服务器端检测来获取。

      【讨论】:

      • 我确实喜欢这个想法,这总比没有好,但这仍然需要用户操作,我们不能假设每个人都会这样做。
      • 我同意,我只是说您可能没有太多其他选择。这是您的情况的限制,而不是我的回答:)
      • 你说得对,如果我找不到更好的解决方案,我会保留这个作为解决方案。感谢您的帮助!
      【解决方案5】:

      也许您可以尝试使用“beforeunload”事件而不是“unload”,例如there,但我认为没有办法通过其他方式延迟窗口关闭。

      【讨论】:

      • 我已经尝试过 beforeunload 但这并没有改变任何东西。
      猜你喜欢
      • 1970-01-01
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 2017-01-21
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 2011-08-29
      相关资源
      最近更新 更多