Synchronous asynchronous JavaScript - Promises
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 | |
* | |
* Utility for making XHR requests | |
* returns a Promise and send response to resolve/reject | |
* | |
* @param {String} url | |
*/ | |
function get(url) { | |
return new Promise(function(resolve, reject) { | |
var req = new XMLHttpRequest(); | |
req.open('GET', url, true); | |
req.onreadystatechange = function() { | |
if(req.readyState != 4) return; | |
if (req.status === 200) { | |
resolve(req); | |
} | |
else { | |
reject(req); | |
} | |
}; | |
req.send(null); | |
}); | |
} | |
/** | |
* Promises | |
*/ | |
// our first async req | |
get('https://api.myjson.com/bins/2qjdn') | |
.then( | |
function(data){ | |
totalTweets.push(data.response); | |
return get('https://api.myjson.com/bins/3zjqz') | |
}) | |
.then( | |
function(data){ | |
totalTweets.push(data.response); | |
return get('https://api.myjson.com/bins/29e3f') | |
}) | |
.then( | |
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; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment