【问题标题】:setInterval is returning the same interval id, when I change browser tabs当我更改浏览器选项卡时,setInterval 返回相同的间隔 id
【发布时间】:2021-01-14 01:16:36
【问题描述】:

我已经在我的节点应用程序和我的反应应用程序中实现了 socket.io。根据我在这里找到的另一个问题的建议,我实现了自己的心跳重置器。它可以工作,当我停止服务器并重新启动它时,客户端会重新连接,但是一旦我更改 chrome 上的选项卡,socket.on("ping") console.logs 两次相同的间隔 id。这是为什么?我的代码是:

  useEffect(() => {
    if (socket && user && socketPingInterval) {
      socket.on("ping", () => {
        console.log("ping received");
        console.log(socketPingInterval);
        clearInterval(socketPingInterval);

        const intervalId = setInterval(() => refreshPing(socket), 1000 * 5);

        if (intervalId !== socketPingInterval) {
          console.log("unique interval id", intervalId);
          setSocketPingInterval(intervalId);
        }
      });

      return () => {
        socket.off("ping");
      };
    }
  }, [socket, user, socketPingInterval]);

socket 只在用户是时才设置,所以 if 语句总是通过,这不是问题。

【问题讨论】:

    标签: reactjs socket.io


    【解决方案1】:

    我通过说解决了它:

      useEffect(() => {
        if (socket && user && socketPingInterval) {
          socket.on("ping", () => {
            console.log("ping received");
            console.log(socketPingInterval);
            clearInterval(socketPingInterval);
    
            const intervalId = setInterval(() => refreshPing(socket), 1000 * 5);
    
            if (intervalId !== socketPingInterval) {
              console.log("unique interval id", intervalId);
              setSocketPingInterval(intervalId);
            } else {
              clearInterval(intervalId);
            }
          });
    
          return () => {
            socket.off("ping");
          };
        }
      }, [socket, user, socketPingInterval]);
    

    【讨论】:

      【解决方案2】:

      实际上,问题在于我传递的是匿名函数,而不是函数引用。所以正确答案是这样的:

      
        useEffect(() => {
          if (socket && user && socketPingInterval) {
            let handler = () => {
              console.log("ping from server", socketPingInterval);
              if (socketConnectionLost) {
                setSocketConnectionLost(false);
                socket.emit("reconnect");
              }
      
              clearInterval(socketPingInterval);
              const intervalId = setInterval(refreshPing, 1000 * 11);
              setSocketPingInterval(intervalId);
            };
      
            socket.on("ping-client", handler);
      
            return () => {
              socket.off("ping-client", handler);
            };
          }
        }, [socket, user, socketPingInterval]);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-16
        • 1970-01-01
        • 1970-01-01
        • 2012-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-03
        相关资源
        最近更新 更多