Created
August 15, 2014 10:47
-
-
Save chrisbuttery/31048839b60fa05b4e25 to your computer and use it in GitHub Desktop.
Synchronous asynchronous JavaScript - Slightly nicer callbacks
This file contains 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 | |
*/ | |
// our first async req | |
function get1stTweet(){ | |
get('https://api.myjson.com/bins/2qjdn', | |
function(data){ | |
totalTweets.push(data.response); | |
get2ndTweet(); | |
}, | |
function(err){ | |
onError(err); | |
} | |
); | |
} | |
// our second async req wrapped in a 2 second delay | |
function get2ndTweet(){ | |
setTimeout(function(){ | |
get('https://api.myjson.com/bins/3zjqz', | |
function(data){ | |
totalTweets.push(data.response); | |
get3rdTweet(); | |
}, | |
function(err){ | |
onError(err); | |
} | |
); | |
}, 2000); | |
} | |
// our third async req | |
function get3rdTweet(){ | |
get('https://api.myjson.com/bins/29e3f', | |
function(data){ | |
totalTweets.push(data.response); | |
showStats(); | |
}, | |
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; | |
} | |
// lets kick it off! | |
get1stTweet(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment