Settings

Theme

Three ways of handling user input

dubroy.com

58 points by joesavage 4 years ago · 16 comments

Reader

kevmo314 4 years ago

Does anyone else find approach #3 to be wildly unintuitive? Like how does an infinite loop terminate? There's a lot of magic going on.

I like approach #1 the best. Sure, there are some bugs, but a state diagram would help make it clearer instead of introducing magic.

  • jayd16 4 years ago

    Its not that unintuitive once you understand async/await and how the tasks are resumed. Execution is yielded at an await. At that time the loop is not running anywhere, its not even in a sleep state. The loop "terminates" by never being resumed.

    • xupybd 4 years ago

      Yeah that's still not the way the code reads. The closer the code behaves to the way it reads the better in my book.

    • ianbicking 4 years ago

      I'm assuming the loop would terminate with an exception... like `await events.pointermove` would raise some cancellation exception that would be silently captured.

      • jayd16 4 years ago

        Sounds like the Abro runtime never resumes the tasks so how could they throw?

        • rexpan 4 years ago

          These 3 functions will stop on `await event.xxx` (if not, they will continue to execute or terminate). So when one of the functions is terminate https://github.com/pdubroy/handling-user-input/blob/main/abr...

             await Promise.any(fibers.map((f) => f.run()));
             fibers.forEach((f) => f.terminate());
          
          Abro will reject the promise of these `await event.xxx` https://github.com/pdubroy/handling-user-input/blob/main/abr...

              this._promises.forEach(({ reject }) => reject());
          
          Which will throw an Exception and exit the 2 other functions.
        • ianbicking 4 years ago

          Oh... on second thought I realize the exception would have to come from `event.pointermove` (for example), and that object doesn't know anything about the receiver or whether it should cancel. So yeah, this does seem problematic.

          • jayd16 4 years ago

            Are you worried about when the case when an exception should be thrown from the thing being awaited? I'm not familiar with Arbo but usually the promise holds on to the exception until its observed. It could be that Arbo is configured to ignore the exception if the task is already cancelled.

    • bruce343434 4 years ago

      Wouldn't that result in a thread leak? (Or a "fiber" leak)

      • jayd16 4 years ago

        If a task has yielded its not holding on to a thread. A loop that wasn't yielding would leak, though.

  • ianbicking 4 years ago

    I feel like approach #3 could have been implemented without abro.or() and it would have been fine and had a little less magic. Though looking at the code I realize you'd need something like `await abro.any(events.pointermove, events.pointerup, windowEvents.keydown)` and a good way to determine which kind of event you got, and finally abro.any() doesn't exist. So maybe abro.or() (representing a group of complementary event handlers) is better than the alternative.

  • bo0tzz 4 years ago

    In javascript this feels like unintuitive magic, but for something like Elixir it's a model that actually makes a lot of sense to me.

_pmf_ 4 years ago

Using Statecharts or FRP is completely orthogonal to the choice of polling vs. event driven.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection