12.07.2015 Views

Pro JavaScript for Web Apps pdf - EBook Free Download

Pro JavaScript for Web Apps pdf - EBook Free Download

Pro JavaScript for Web Apps pdf - EBook Free Download

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 9 WRITING BETTER JAVASCRIPTI have used Modernizr to test some indicator that jQuery has already been loaded and use the nopeproperty to load the <strong>JavaScript</strong> file if it hasn’t. Applying this technique to my tiny example web app willmake everything work. But it isn’t a real solution, and while the new problem I created occurs lessfrequently, it is much harder to track down.The underlying problem is that I am still just trying to make my code work. If utils.js is the only filethat uses this technique, then everything will be fine, with the exception that the map<strong>Pro</strong>ducts functionmay not be defined in a timely enough manner if the jQuery library does need to be loaded and there is adelay in the request. However, if this technique is used in more than one file, then there is a very subtlerace condition. Imagine that there are two files that use Modernizr to test <strong>for</strong> jQuery: fileA.js andfileB.js. Most of the time, the sequence of events will be this:1. The browser executes the code in fileA.js, which tests <strong>for</strong> jQuery. jQueryhasn’t been loaded, so Modernizr requests the file and then executes thecomplete function.2. The browser executes the code in fileB.js, which tests <strong>for</strong> jQuery. jQuery hasbeen loaded via fileA.js, and Modernizr executes the complete functionwithout needing to load any files.However, Modernizr requests are asynchronous, which means that the browser will continue toexecute <strong>JavaScript</strong> code while Modernizr waits <strong>for</strong> the response from the server. So, if the timing is justright, the sequence will really be as follows:1. The browser executes the code in fileA.js, which tests <strong>for</strong> jQuery. jQueryhasn’t been loaded, so Modernizr requests the file.2. The browser continues to execute code while Modernizr is waiting and beginsprocessing fileB.js. The Modernizr request from fileA.js hasn’t completedyet, so fileB.js causes Modernizr to make a second request <strong>for</strong> the jQuery file.3. The fileA.js request completes, jQuery is loaded, and the fileA.js completefunction is executed.4. The fileB.js request completes, jQuery is loaded <strong>for</strong> a second time, and thefileB.js complete function is executed.Any properties that the complete function in fileA.js adds to the jQuery $ shorthand will be lostwhen Modernizr loads jQuery again. This sequence occurs infrequently, but when it does, it can kill theweb app by deleting essential functionality required in at least one of the <strong>JavaScript</strong> files. You mightthink that infrequent problems are acceptable, but infrequent can still be a serious issue when your webapp has millions of users.Using the Asynchronous Module DefinitionThe only real way to eliminate race conditions and duplicated library loading is to deal withdependencies in a coordinated way, and this means taking responsibility <strong>for</strong> loading dependencies outof individual <strong>JavaScript</strong> files and consolidating them. The best model <strong>for</strong> doing this is the AsynchronousModule Definition (AMD), which I’ll explain and demonstrate in the sections that follow.244www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!