首页 > 解决方案 > 反应原生 0.63.3 | 使用 chrome 调试器时 setInterval 不起作用

问题描述

我有一个严重依赖间隔和超时的专有应用程序。当我尝试调试间隔之前/之后发生的问题时,没有任何效果,因为间隔永远不会触发。

这是我如何使用间隔的片段(假设所有功能都已实现):

useEffect(() => {
    let timerInterval;

    const stopTimer = () => {
      clearInterval(timerInterval);
    };

    subTimerStarted(() => {
      stopTimer();
      timerInterval = setInterval(() => {
        tick();
        if (store.getState().time <= 0) {
          clearInterval(timerInterval);
        }
      }, 1000);
    });

    subTimerReset(stopTimer);
}, []);

当 chrome 调试器处于活动状态setInterval时,将永远不会触发。研究告诉我,这是因为我的工作站和设备的时钟不同步。我不明白为什么这应该是一个问题,因为设备应该完成所有工作,并且只是向调试器发送信号,通知它它的当前状态。这是不可接受的,我需要正确访问调用堆栈来解决这些问题。

我已经看过的资源:

非选项:

细节

由于 NDA,我不能展示太多,除了那个代码示例 ^ 和这些:

包.json


{
  "main": "index.js",
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "web": "expo start --web",
    "start": "react-native start --reset-cache",
    "test": "jest",
  },
  "dependencies": {
    "@apollo/client": "^3.3.9",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-navigation/native": "^5.8.1",
    "@react-navigation/stack": "^5.11.0",
    "bluebird": "^3.7.2",
    "buffer": "^6.0.3",
    "color": "^3.1.3",
    "expo": "~39.0.2",
    "expo-splash-screen": "~0.6.2",
    "expo-status-bar": "~1.0.2",
    "expo-updates": "~0.3.2",
    "graphql": "^15.5.0",
    "lodash.ismatch": "^4.4.0",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "~0.63.3",
    "react-native-cookies": "^3.3.0",
    "react-native-exit-app": "^1.1.0",
    "react-native-fs": "^2.16.6",
    "react-native-gesture-handler": "~1.7.0",
    "react-native-reanimated": "~1.13.0",
    "react-native-restart": "0.0.20",
    "react-native-safe-area-context": "^3.1.9",
    "react-native-screens": "~2.10.1",
    "react-native-share": "^5.1.0",
    "react-native-sidebar": "^0.3.0",
    "react-native-svg": "^12.1.0",
    "react-native-svg-transformer": "^0.14.3",
    "react-native-unimodules": "~0.11.0",
    "react-native-uuid": "^1.4.9",
    "react-native-vector-icons": "^7.1.0",
    "react-native-web": "~0.13.12",
    "react-native-webview": "^11.0.2",
    "react-redux": "^7.2.2",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0",
    "regression": "^2.0.1"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "babel-jest": "~25.2.6",
    "jest": "~25.2.6",
    "react-test-renderer": "~16.13.1"
  },
  "jest": {
    "preset": "react-native"
  },
  "private": true,
  "version": "1.0.0"
}
react-native info                                                                                                                 ~/Documents/node/obm-app  
info Fetching system and libraries information...
(node:1581462) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
System:
    OS: Linux 5.10 Manjaro Linux
    CPU: (20) x64 Intel(R) Core(TM) i9-10850K CPU @ 3.60GHz
    Memory: 7.08 GB / 31.26 GB
    Shell: 5.8 - /usr/bin/zsh
  Binaries:
    Node: 15.14.0 - /usr/local/bin/node
    Yarn: 1.22.10 - /usr/bin/yarn
    npm: 7.7.6 - /usr/local/bin/npm
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 23, 25, 29, 30
      Build Tools: 28.0.3, 29.0.2, 29.0.3, 30.0.3
      System Images: android-25 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom, android-30 | Google APIs Intel x86 Atom
      Android NDK: Not Found
  IDEs:
    Android Studio: 4.1 AI-201.8743.12.41.7199119
  Languages:
    Java: 1.8.0_292 - /usr/bin/javac
    Python: 3.9.4 - /usr/bin/python
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.13.1 => 16.13.1 
    react-native: ~0.63.3 => 0.63.4 
  npmGlobalPackages:
    *react-native*: Not Found

标签: javascriptreact-nativereact-native-androidsetintervalremote-debugging

解决方案


在做你正在做的事情时,我通常会使用一个全局变量。您可以在任何地方使用 clearInterval(timerInterval) 而无需将其保存到状态。

let timerInterval; //<-- timer variable here

const Component = () => {

useEffect(() => {
      //stopTimer(); <-- u don't need this since u r running this useEffect only on mounted.
      timerInterval = setInterval(() => {
        tick();
        if (store.getState().time <= 0) {
          clearInterval(timerInterval);
        }
      }, 1000);

//    subTimerReset(stopTimer); //<- don't need this

   () => { clearInterval(timeInterval) } //<-- clean up function

}, []);

...

}

顺便说一句,您是否尝试将函数保存到状态?

subTimerReset(stopTimer)

推荐阅读