question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

binding the same handler to the same event with once() can have unexpected results

See original GitHub issue

I haven’t investigated to precisely determine the mechanism of the bug, but the behavior i saw was that binding the same handler to the same event with once multiple times would remove the wrong handler after firing.

so for example, you have an object which provides a token: myObject.getToken(), but my object is instantiated by an asynchronous process, you might write code like:

let tokenPromise = ()=>{
  if(myObject) {
    return new Promise((resolve) => {
        resolve(myObject.getToken())
    })
  }
  return new Promise((resolve)=>{
      emitter.once('MY_OBJECT_CREATED', ()=>{
        resolve(myObject.getToken())
      })
  })
}

multiple calls to tokenPromise results in the wrong handlers being unbound by once, i believe to confusion around the value of ‘fn’ within the once() method.

this seems to resolve the issue:

    once: function once (name, handler) {
      function fn (a, b, c) {
        app.off(name, this);
        handler(a, b, c);
      }

      return app.on(name, fn.bind(fn))
    }

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:14 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
nihltoncommented, Mar 20, 2017

also, just my two cents, but this isn’t ideal:

fn.sourceString = handler.toString();

what if i’m using ‘sourceString’? or what if i’m not expecting any additional properties on the handler? just my opinion, but you shouldn’t modify the handlers passed to you…

but its your show 😃

thanks for looking into the issue.

1reaction
tunnckoCorecommented, Mar 18, 2017

Heya! Thanks for the report. I think problems mainly come from .off. Can you try the same example with .on method and report back, I believe it will have the same problem.

this seems to resolve the issue:

Mainly, I don’t want to rely on this, bind, apply and etc. The only thing where i found a need for .apply is in the .emit, because is the smallest solution to not call handlers with undefined - example:

emitter.on('foo', function (a, b, c) {
  console.log(a, b, c) // => 1, undefined, undefined
  console.log(arguments.length) // => 3, it should be 1
})
emitter.emit('foo', 1)
Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - Attaching an event handler multiple times - Stack Overflow
If you only need it to be raised once then assign one handler. If you attach the same handler 4 times then it...
Read more >
Introduction to events - Learn web development | MDN
Objects that can fire events have an addEventListener() method, ... Also, the ability to remove event handlers allows you to have the same...
Read more >
Event delegation - The Modern JavaScript Tutorial
In the handler we get event.target to see where the event actually happened and handle it. Let's see an example – the Ba-Gua...
Read more >
How to Share a Variable Between Two Event Handlers in ...
Let's take a look at a few different ways we can share data between event handlers. ... Then, a script to handle the...
Read more >
Understanding This, Bind, Call, and Apply in JavaScript
Both call and apply are one-time use methods—if you call the method with the this context it will have it, but the original...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found