Created
August 15, 2014 10:46
-
-
Save chrisbuttery/349cad51f9f8373aeda0 to your computer and use it in GitHub Desktop.
Synchronous asynchronous JavaScript - Callback hell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <html> | |
| <head> | |
| <style> | |
| body { | |
| background: #f5f8fa; | |
| font: 16px/22px Arial, sans-serif; | |
| margin: 0; | |
| } | |
| .statList { | |
| background: #fff; | |
| border-bottom: 1px solid #e1e8ed; | |
| height: 60px; | |
| overflow: hidden; | |
| } | |
| .statList__item { | |
| float: left; | |
| width: 75px; | |
| height: 60px; | |
| display: table; | |
| } | |
| .status { | |
| display: table-cell; | |
| text-align: center; | |
| text-transform: uppercase; | |
| vertical-align: middle; | |
| } | |
| .title { | |
| color: #66757f; | |
| font-size: 11px; | |
| letter-spacing: .02em; | |
| text-transform: uppercase; | |
| } | |
| .count { | |
| color: #C29A34; | |
| font-size: 18px; | |
| font-weight: 500; | |
| padding-top: 3px; | |
| } | |
| .tweetFeed { | |
| margin: 10px; | |
| } | |
| .tweet { | |
| background: #fff; | |
| border: 1px solid #e1e8ed; | |
| padding: 15px; | |
| } | |
| .tweet:nth-child(1){ | |
| border-radius: 5px 5px 0 0; | |
| } | |
| .tweet:nth-child(n+2){ | |
| border-top: none; | |
| } | |
| .tweet__name{ | |
| color: #292f33; | |
| display: inline-block; | |
| font-size: 14px; | |
| font-weight: bold; | |
| } | |
| .tweet__handle { | |
| color: #8899a6; | |
| display: inline-block; | |
| font-size: 13px; | |
| margin-left: 10px; | |
| } | |
| .tweet__message { | |
| margin-top: 5px; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="statList"> | |
| <div class="statList__item"> | |
| <div class="status"> | |
| <div class="title">Tweets</div> | |
| <div class="count totalTweets"></div> | |
| </div> | |
| </div> | |
| <div class="statList__item"> | |
| <div class="status"> | |
| <div class="title">Photos</div> | |
| <div class="count totalPhotos"></div> | |
| </div> | |
| </div> | |
| <div class="statList__item"> | |
| <div class="status"> | |
| <div class="title">Favourites</div> | |
| <div class="count totalFavourites"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="tweetFeed"> | |
| <div class="timeLine"></div> | |
| </div> | |
| <script type="text/javascript"> | |
| var timeLine = document.querySelector('.timeLine'); | |
| var totalTweets = []; | |
| /** | |
| * get | |
| * | |
| * Tiny utility for making XHR requests | |
| * @param {String} url | |
| * @param {Function} callback [description] | |
| */ | |
| function get(url, callback, errback) { | |
| var req = new XMLHttpRequest(); | |
| req.open('GET', url, true); | |
| req.onreadystatechange = function() { | |
| if(req.readyState != 4) return; | |
| if (req.status === 200) { | |
| callback(req); | |
| } | |
| else { | |
| errback(req); | |
| } | |
| }; | |
| req.send(null); | |
| } | |
| /** | |
| * Asynch Requests | |
| * Nest callback grossness | |
| */ | |
| // our first async req | |
| get('https://api.myjson.com/bins/2qjdn', | |
| function(data){ | |
| totalTweets.push(data.response); | |
| // our second async req wrapped in a 2 second delay | |
| setTimeout(function(){ | |
| get('https://api.myjson.com/bins/3zjqz', | |
| function(data){ | |
| totalTweets.push(data.response); | |
| // our third async req | |
| get('https://api.myjson.com/bins/29e3f', | |
| function(data){ | |
| totalTweets.push(data.response); | |
| showStats(); | |
| }, | |
| function(err){ | |
| onError(err); | |
| } | |
| ); | |
| }, | |
| function(err){ | |
| onError(err); | |
| } | |
| ); | |
| }, 2000); | |
| }, | |
| function(err){ | |
| onError(err); | |
| } | |
| ); | |
| /** | |
| * showStats | |
| * | |
| * Populate some stats | |
| */ | |
| function showStats(){ | |
| var totalTweets = document.querySelector('.totalTweets'); | |
| totalTweets.textContent = countProperties('user') || 0; | |
| var totalPhotos = document.querySelector('.totalPhotos'); | |
| totalPhotos.textContent = countProperties('photo') || 0; | |
| var totalFavourites = document.querySelector('.totalFavourites'); | |
| totalFavourites.textContent = countProperties('favourited') || 0; | |
| showTimeline(); | |
| } | |
| /** | |
| * showTimeline | |
| * | |
| * Flesh out some sweet sweet tweet data | |
| * then append to the .timeLine | |
| */ | |
| function showTimeline(){ | |
| var el = document.createElement('div'); | |
| totalTweets.forEach(function(tweet){ | |
| tweet = JSON.parse(tweet); | |
| var tweetElement = el.cloneNode(true); | |
| tweetElement.classList.add('tweet'); | |
| var name = el.cloneNode(true); | |
| name.classList.add('tweet__name'); | |
| name.textContent = tweet.user.name; | |
| var handle = el.cloneNode(true); | |
| handle.classList.add('tweet__handle'); | |
| handle.textContent = '@' + tweet.user.handle; | |
| var message = el.cloneNode(true); | |
| message.classList.add('tweet__message'); | |
| message.textContent = tweet.message; | |
| tweetElement.appendChild(name); | |
| tweetElement.appendChild(handle); | |
| tweetElement.appendChild(message); | |
| timeLine.appendChild(tweetElement); | |
| }); | |
| } | |
| /** | |
| * OnError | |
| * | |
| * @param {error} err | |
| */ | |
| function onError (err) { | |
| console.error("Error: err"); | |
| } | |
| /** | |
| * countProperties | |
| * | |
| * Utility function to help us count certain props | |
| * | |
| * @param {String} a specific prop | |
| * @return {Number} count | |
| */ | |
| function countProperties(prop) { | |
| var count = 0; | |
| totalTweets.forEach(function(tweet){ | |
| tweet = JSON.parse(tweet) | |
| if (prop in tweet) count++; | |
| }); | |
| return count; | |
| } | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment