JavaScript Async - Events
Written by Ian Elliot   
Monday, 21 August 2017
Article Index
JavaScript Async - Events
Bubbling & Controlling Events
True Asynchronous Events

Normally JavaScript promises that no events will be handled until your code completes but if you use dispatchEvent this is no longer true.

You can create true asynchronous events if you want to. 

The Key to doing this are the setInterval and setTimeOut functions. These will place a message in the event queue that calls a function after a set time. The setInterval function arranges to call the function repeatedly at the set interval.

You may already be familiar with these functions as ways of calling functions after a delay or periodically, but they can also be used to create a custom asynchronous event.

All you have to do is call setTimeOut with a delay of zero and use it to dispatch the event:

console.log("Before Event");
setTimeout(function(){
              button1.dispatchEvent(event);
             },0);
console.log("After Event")

This  effectively puts the function that dispatches on the event queue and then returns immediately. Of course, the function will not be processed by the event queue until the UI thread is released and so now what you see is;

Before Event
After Event
MyEvent

which is the asynchronous behavior of a true event.

In practice you can wrap the setTimeout in a suitable function and hide a little of what is going on:

function fireEvent(elem, ev) {
 var event = new Event(ev, {
                    'bubbles': true,
                    'cancelable': true
                  });
 setTimeout(function () {
                     elem.dispatchEvent(event);
                 },
 0); }

With this function defined we can simply write:

console.log("Before Event");
fireEvent(button1, "myEvent");
console.log("After Event");

The difference between synchronous and asynchronous events is important - make sure you are using the correct implementation..

Working With The Dispatch Queue

It is worth noting that the setTimeout function is one of the few ways you have of interacting with the dispatch queue. You can use it to add any function to the dispatch queue using a time delay of zero. The only problem is that the HTML5 specification limits the time delay to a minimum of 4ms. This is enforced by most browsers and this means that your custom event is going to a little slower than you might expect from a zero millisecond delay. Some older browsers make use of an even longer minimum delay of 10ms. Of course the timeout will not happen until the function that used setTimeout finishes and hands back the UI thread to the dispatcher.

If you demand the fastest custom event handling then you need to make use of the window.postMessage method which is only supported in modern browsers.

This will send a message which causes a message event o another window. If all you want to do is add an event to the event queue you can use it to send a message to the same window:

window.postMessage("fireEvent", "*");

This places a message event into the event queue with the message payload "fireEvent", As soon as the UI thread is free to process events a message event occurs on the current window. There is no minimum delay in using postMessage.

A version of the fireEvent utility function using postMessage is easy to create:

function fireEvent(elem, ev) {
 var event = new Event(ev);
 var fire = function (e) {
  elem.dispatchEvent(event);  
  window.removeEventListener("message",fire,false); 
 };
window.addEventListener("message", fire, false);
window.postMessage("fireEvent", "*");
}

This sets up a function, fire, which triggers the custom event. It then adds fire to respond to the message event. After this the event is added to the event queue. When the UI thread is freed the message event occurs and triggers fire which in turn runs the custom event and removes fire as a message event handler so that it will not be accidentally triggered again.

You can, of course, improve on this function and you might want to leave an event handler attached to the window message event ready to handle custom events.

Summary

  • The JavaScript UI is single threaded.

  • The dispatcher uses the UI thread to handle events. When an event happens it is added to the dispatch queue and the dispatcher allows each event to execute on the UI thread in turn.

  • Once an event handler has the UI thread then it keeps it until it has finished.

  • This means that while any JavaScript code is running no other event can be handled and the UI is unresponsive.

  • If an event handler runs for a long time then the user will notice that the UI has frozen.

  • The ideal JavaScript program does nothing but leave the UI thread idle waiting to service an event.

  • You can add event handlers to an object using its addEventListener method.

  • An object can have multiple event handlers in its event listener list.

  • Bubbling and capture make event handling most sophisticated and implementation simpler.

  • You can trigger an event, existing or custom, using the object's dispatchEvent method with a suitable Event object.

  • The dispatchEvent method behaves more like a function call than a true event. That is, it creates a synchronous event.

  • If you need a true asynchronous event then you need to use the setTImeout method to add a function which triggers the event to the dispatch queue.

Now Available as a Book:

 JavaScript Async

cover

You can buy it from: Amazon

Contents

  1. Modern JavaScript (Book Only)
  2. Events,Standard & Custom
  3. The Callback
      extract - The Callback & The Controller
  4. Custom Async - setTimeout, sendMessage & yield
      extract - Custom Async
      extract - Avoiding State With Yield 
  5. Worker Threads
      extract - Basic Worker ***NEW
      extract - Advanced Worker Threads 
  6. Consuming Promises 
  7. Producing Promises
      extract - The Revealing Constructor Pattern
     
    extract - Returning Promises
     
    extract - Composing Promises
  8. The Dispatch Queue
      extract - Microtasks
  9. Async & Await
      extract -  Basic Async & Await
      extract -  DoEvents & Microtasks
  10. Fetch, Cache & Service Worker
      extract - Fetch  
      extract - Cache
     
    extract -  Service Workers

 

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

raspberry pi books

 

Comments




or email your comment to: comments@i-programmer.info

 <ASIN:1871962528>

<ASIN:1871962501>



Last Updated ( Monday, 21 August 2017 )