Browse Month

August 2014

How the JavaScript Event Loop Works

Event Loop

JavaScript has this system called an event loop. I’m not sure if my idea of it is exactly correct, but I will try to explain it from what I can recall from the lecture.

So basically, the event loop is something that is continuously running in the background of your website only if there is nothing in the call stack. It does 3 things:

  1. Invokes functions sitting in the call stack.
  2. Checks the event table for functions.
  3. Checks the message queue for functions.

Call Stack

The call stack contains functions that need to be invoked. If the functions have any callbacks, those will get added into the event table to be invoked when it is time to do so.

Example: Let’s say the current time is 2:00:00pm, and the call stack contains this function that logs “Hello World” after 1 second.

setTimeout(console.log("Hello World"), 1000);

That will get invoked, and the callback function console.log(“Hello World”)  would be added to the event table with the time set to 2:00:01pm.

Event Table

The event table stores more functions with the specific time that they should be ran. If the time in the table is greater or equal to the current time, then the function will be moved to the message queue.

Example: console.log(“Hello World”)  would only be added to the message queue when the clock has turned to 2:00:01pm.

Message Queue

Lastly, the message queue contains functions that are next in line to be ran. These functions will be popped off the queue and be added to the call stack.

Example: console.log(“Hello World”)  will be moved into the call stack. This completes a full circle, and the event loop will repeat again.

My Two-Day Solo MVP Project

YouTube Live

For my two-day solo Minimum Viable Product Project, I decided to make a website for sharing synchronized YouTube videos. This website would be good for people who want to watch a YouTube video together, at the same time, but aren’t in the same room. (Or maybe they are in the same room, but want to watch on separate devices.)

The user who enters a URL (a host) can play, pause, and seek the video. The users who watch the video (the viewers) will have their embedded players behave exactly the same as the host’s player. Pretty simple.

Scoping

My original idea had more features, but I quickly learned that I had to cut down the scope, and then cut it down again for it to be do-able in two days. I was going to have user sessions/authentication, rooms, and a chat box. I was also going to use Angular. But all those went away.

Requirements

The tools that I ended up using for this project are:

  • Node.js for the server
  • Firebase for the database
  • jQuery for getting the URL from the input box
  • YouTube Player IFrame API

Player API Functions

After embedding the YouTube player on my website, I needed access to some of the functionality. With the API, I was able to use these functions:

First, I use loadVideoById()  to load a YouTube video when a URL is submitted.

Then when the host’s player starts playing, the viewers will invoke playVideo() , otherwise pauseVideo()  in all other cases. I don’t use stopVideo()  because that will stop the player from buffering.

When the host is in paused state and moves the video to a new time position, this will invoke getCurrentTime() . The viewers will invoke seekTo()  to be at the new location.

Database

I’ve spent 15 minutes playing with Firebase during one of the other projects before, so I know how easy it is to set and get data. I love how Firebase automatically sends a trigger back to the website when a value is changed in the database.

In my Firebase database, I store 3 things:

  1. The state of the host’s video player (playing, paused, buffering, etc.)
  2. The YouTube video ID that the host is watching
  3. The time position of the host’s video player

Whenever host played or paused a video, Firebase sent a trigger which would invoke a callback function to play/pause all of the viewers’ video players. It was pretty simple.

If the host seeked the video ahead, Firebase would get the new time position, which would then again trigger a callback on the viewers’ video players and move them to the new time.

Same thing will happen when the host enters a new YouTube video ID.

Extra Feature

I also had some extra time, so I was able to add a search feature. The host can input search terms, and the first video result of the query will be loaded.

This is done by using the loadPlaylist()  function and passing this object for the argument:

{
  listType: 'search',
  list: 'the keywords to search'
}

Using this function will actually load a playlist of the first 20 videos found in the search, which I don’t want. So when the first video is playing, I invoke getVideoUrl()  to get the video’s URL, then I save the video ID to Firebase, and then play the video by ID to clear the playlist.

Stumbling Block

An obstacle that I ran into about 1 hour into the project was that I chose to use the YouTube Player JavaScript API. That doesn’t seem like a problem at all, right? Well, it wouldn’t be if the JavaScript API was able to embed the HTML5 video player. However, it only embeds the Flash video player, which iPhones and Androids don’t support! So the solution was kind of simple; I switched to the YouTube Player IFrame API.

Final Result

I deployed my code onto the Microsoft Azure platform, and you can view it here: http://youtube.azurewebsites.net/

YouTube Live Player