Created
April 19, 2017 03:16
-
-
Save dezull/b11e7653c14102bd8a285198021ab63c to your computer and use it in GitHub Desktop.
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
// Stub Implementation | |
// =================== | |
function notify (msg) { console.log(msg) } | |
function renderListItem () { /* UI update goes here */ } | |
var movieApi = { | |
titles: [ | |
'IV – A New Hope (1977)', | |
'V – The Empire Strikes Back (1980)', | |
'VI – Return of the Jedi (1983)', | |
'I – The Phantom Menace (1999)', | |
'II – Attack of the Clones (2002)', | |
'III – Revenge of the Sith (2005)', | |
'VII – The Force Awakens (2015)', | |
'VIII – The Last Jedi (2017)' | |
], | |
fetchTitles: function (cb) { | |
// Pretending to download titles... | |
var titles = this.titles | |
setTimeout(function () { | |
// Remove the last one 80% of the time, then shuffle the list a bit | |
titles = titles.slice(0, titles.length - (Math.ceil(Math.random() * 9) > 7 ? 0 : 1)) | |
titles.sort(function () { return 1 - (Math.ceil(Math.random() * 3) - 1) }) | |
cb(null, titles) | |
}, 1000) | |
}, | |
fetchSynopsis: function (title, cb) { | |
// Pretending to download the synopsis | |
var titles = this.titles | |
setTimeout(function () { | |
if (title === titles[titles.length - 1]) { | |
cb(new Error(title + ' is in the making!')) | |
} else { | |
cb(null, title + ' jeng'.repeat(4)) | |
} | |
}, Math.random() * 200) | |
} | |
} | |
// The application | |
// =============== | |
function createQueue (taskCb, drainCb, concurrency) { | |
var processing = 0 | |
var queue = [] | |
concurrency = concurrency || 1 | |
function log (msg) { notify('[queue] ' + msg) } | |
function drained () { return !processing && !queue.length } | |
function process () { | |
if (drained()) { | |
log('drained') | |
return drainCb() | |
} | |
if (processing < concurrency) { | |
var data = queue.pop() | |
if (!data) return | |
processing++ | |
log('processing: ' + processing + ', queued: ' + queue.length) | |
taskCb(data, function () { | |
setTimeout(function () { | |
processing-- | |
process() | |
}, 0) | |
}) | |
} | |
} | |
this.push = function (data) { | |
queue.push(data) | |
process() | |
} | |
return this | |
} | |
function fetchEachSynopsis (titles, synopsisCb, doneCb) { | |
function task (title, taskDoneCb) { | |
movieApi.fetchSynopsis(title, function (err, synopsis) { | |
synopsisCb(err, title, synopsis) | |
taskDoneCb() | |
}) | |
} | |
var queue = createQueue(task, doneCb, 2) | |
titles.forEach(function (title) { queue.push(title) }) | |
} | |
function fetchEachMovie (movieCb, doneCb) { | |
movieApi.fetchTitles(function (err, titles) { | |
if (err) return doneCb(err) | |
fetchEachSynopsis(titles, movieCb, doneCb) | |
}) | |
} | |
function updateUIAtInterval (interval) { | |
notify('Fetching latest titles') | |
fetchEachMovie( | |
function each (err, title, synopsis) { | |
if (err) return notify('Error fetching synopsis!. Reason: ' + err.message) | |
notify('Fetched synopsis ' + synopsis) | |
// Update UI | |
renderListItem(title, synopsis) | |
}, | |
function done (err) { | |
notify('Done fetching all synopsis, error: ' + (err || 'none')) | |
setTimeout(updateUIAtInterval.bind(null, interval), interval) | |
} | |
) | |
} | |
// Start the program | |
var interval = 60 * 60 * 1000; | |
updateUIAtInterval(interval) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment