Skip to content

[BUG] setTimeout fires incorrectly when using chrome debug #4470

Closed

Description

@Thomas101

Hey,

I've found an issue that means when you're running on an iOS device and debugging in chrome setTimeouts can fire in the wrong order. If you place the following code block into a fresh app and run it you should get the error...

  componentDidMount:function() {
    this.runTest()
  },

  test:function(cb) {
    var aFired = false
    var bFired = false
    var aExpected = new Date().getTime()+130
    var bExpected = new Date().getTime()+500
    console.log('Schedule A to fire @' + aExpected)
    console.log('Schedule B to fire @' + bExpected)

    var a = setTimeout(() => {
      var now = new Date().getTime()
      console.log('A fired', now, now - aExpected)
      aFired = true
      if (bFired) { console.log('ERROR: b fired early'); return;
      }
      if (aFired && bFired) { cb() }
    }, 130)
    var b = setTimeout(() => {
      var now = new Date().getTime()
      console.log('B fired', now, now - bExpected)
      bFired = true
      if (!aFired) { console.log('ERROR: A not fired'); return;
      }
      if (aFired && bFired) { cb() }
    }, 500)
  },
  runTest:function() {
    this.test(() => {
      setTimeout(() => {
        this.runTest()
      }, 500)
    })
  },

On the console you'll get something like...

index.ios.js:25 Schedule A to fire @1448977966848
index.ios.js:26 Schedule B to fire @1448977967218
index.ios.js:30 A fired 1448977966754 -94
index.ios.js:38 B fired 1448977966755 -463
index.ios.js:25 Schedule A to fire @1448977966902
index.ios.js:26 Schedule B to fire @1448977967272
index.ios.js:30 A fired 1448977966806 -96
index.ios.js:38 B fired 1448977966806 -466
index.ios.js:25 Schedule A to fire @1448977966951
index.ios.js:26 Schedule B to fire @1448977967321
index.ios.js:30 A fired 1448977966835 -116
index.ios.js:38 B fired 1448977966835 -486


index.ios.js:25 Schedule A to fire @1448977966983
index.ios.js:26 Schedule B to fire @1448977967353
index.ios.js:38 B fired 1448977966871 -482
index.ios.js:40 ERROR: A not fired
index.ios.js:30 A fired 1448977966871 -112
index.ios.js:32 ERROR: b fired early

... with the first 3 firing correctly and the last one incorrectly. I believe this bug is also what is causing issue #1693 as one of the setTimeout functions sometimes fires early in touchableHandleResponderGrant

Activity

  1. facebook-github-bot commented on Dec 1, 2015

    @facebook-github-bot
    Contributor

    Hey Thomas101, thanks for reporting this issue!

    React Native, as you've probably heard, is getting really popular and truth is we're getting a bit overwhelmed by the activity surrounding it. There are just too many issues for us to manage properly.

    • If this is a feature request or a bug that you would like to be fixed by the team, please report it on Product Pains. It has a ranking feature that lets us focus on the most important issues the community is experiencing.
    • If you don't know how to do something or not sure whether some behavior is expected or a bug, please ask on StackOverflow with the tag react-native or for more real time interactions, ask on Discord in the #react-native channel.
    • We welcome clear issues and PRs that are ready for in-depth discussion; thank you for your contributions!
  2. christopherdro commented on Dec 1, 2015

    @christopherdro
    Contributor

    @Thomas101 Try taking a look at https://facebook.github.io/react-native/docs/timers.html#timermixin at the last paragraph:
    We strongly discourage using the global setTimeout(...) and recommend instead that you use this.setTimeout(...)

  3. Thomas101 commented on Dec 1, 2015

    @Thomas101
    ContributorAuthor

    Thanks @christopherdro, we've been using that wherever possible but some of the built in react functionality uses plain old settimeout which is where the bug raised its head initially

  4. ide commented on Dec 1, 2015

    @ide
    Contributor

    @Thomas101 Thanks for your detailed investigation and write-up. RN should implement timers correctly. In fact if I'm reading your code and logs correctly, it looks like the timeout arg is ignored as events A and B run at almost the same time. cc @sahrens

  5. Thomas101 commented on Dec 1, 2015

    @Thomas101
    ContributorAuthor

    Those were the logs that came out, you should get similar results if you run it yourself. This is purely speculation as I haven't looked at the implementation, but as it only happenens when running the chrome debugger and using the device, did wonder if it could be a time drift issue between my Mac and ipad?

  6. satya164 commented on Dec 3, 2015

    @satya164
    Contributor

    @christopherdro Also not possible to use it when using the ES6 class syntax. Need to manually cleanup ofc.

  7. sahrens commented on Dec 5, 2015

    @sahrens
    Contributor

    Not sure who owns timers these days - maybe @tadeuzagallo or @nicklockwood ? Also cc @dmmiller because we want to be consistent on iOS and android.

  8. aleclarson commented on Jan 6, 2016

    @aleclarson
    Contributor

    I've experienced this while "Debug in Chrome" is active. setTimeout fires very early.

    Has it been confirmed that TimerMixin avoids this issue?

    I thought TimerMixin only helps with cleanup in componentWillUnmount?

  9. Thomas101 commented on Jan 7, 2016

    @Thomas101
    ContributorAuthor

    Hi @aleclarson using the TimerMixin still has the same problem as this uses setTimeout behind the scenes.

  10. aleclarson commented on Jan 8, 2016

    @aleclarson
    Contributor

    Who works on the debugger-proxy packager endpoint? Is there a hack related to setTimeout that involves accounting for socket latency? I can't imagine how else setTimeout could be acting so strangely.

  11. PaulBGD commented on Jan 9, 2016

    @PaulBGD

    Go vote for this issue so that the developers can see that it's important: https://productpains.com/post/react-native/settimeout-fires-incorrectly-when-using-chrome-debug/

  12. sahrens commented on Jan 9, 2016

    @sahrens
    Contributor

    I don't know much about our chrome integration or why it would cause a difference in timer behavior - @frantic or @tadeuzagallo?

  13. aleclarson commented on Jan 12, 2016

    @aleclarson
    Contributor

    Would it be worth implementing a native shim for setTimeout and clearTimeout?

  14. satya164 commented on Jan 19, 2016

    @satya164
    Contributor

    Any updates on this?

  15. 24 remaining items

  16. alpfilho commented on Aug 9, 2017

    @alpfilho

    still an issue in 0.46.4

  17. dave-irvine commented on Aug 24, 2017

    @dave-irvine

    Still an issue on 0.47.x as far as I can tell

  18. emusgrave commented on Sep 5, 2017

    @emusgrave

    @Odinvt Did you consider integrating your library into a PR for the core RN library? I'm curious if the team would accept it as a solution for this issue.

  19. Odinvt commented on Sep 5, 2017

    @Odinvt

    @emusgrave I thought about it and I would love to, but I don't think that the PR will be merged because first of all, it's an ugly hack and second of all, it's not a modification of react native's source code, it's only a modification of another package ( React Native Timer ) which would force devs to use the package's overridden methods instead of the classic JS setTimeout and setInterval methods...

    The source code is there, we've been using it for 4 months in our dev env for our projects and it's proven its worth. I encourage anyone who has the time to make those changes in RN's source code and submit a PR to do so, I think that the idea is there but the code still needs some refactoring and tests should be written. I hope you're all having fun creating stuff with RN as I know I do <3

  20. kesha-antonov commented on Oct 17, 2017

    @kesha-antonov
    Contributor

    RN 0.50 Same issue

  21. ahmb84 commented on Nov 13, 2017

    @ahmb84

    Same issue from RN 0.50.3

  22. loveky commented on Dec 13, 2017

    @loveky

    any update on this? just spent about 1 hour and see this issue... 😞

  23. jacklovepdf commented on Dec 15, 2017

    @jacklovepdf

    close the debugger model

  24. Vishal-vash commented on Dec 20, 2017

    @Vishal-vash

    I had similar issue using onLongPress with debugger open and it fires the event as onPress , So onLongPress also don't work accurately in debugger mode similar to setTimeout/setInterval

  25. dhirendrarathod2000 commented on Mar 19, 2018

    @dhirendrarathod2000

    RN 0.53
    Not working

  26. fatfatson commented on Apr 18, 2018

    @fatfatson

    sync your emulator and host' time by:

    adb shell su root date $(get-date -format MMddHHmmyyyy.ss)

  27. Sharcoux commented on May 12, 2018

    @Sharcoux

    get-date -> unknown command.

    I had better luck with:

    adb shell su root "date `date +%m%d%H%M%Y.%S`"
    
  28. locked as resolved and limited conversation to collaborators on Jul 20, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions