Skip to content

Instantly share code, notes, and snippets.

@dezull
Created April 19, 2017 03:16
Show Gist options
  • Save dezull/b11e7653c14102bd8a285198021ab63c to your computer and use it in GitHub Desktop.
Save dezull/b11e7653c14102bd8a285198021ab63c to your computer and use it in GitHub Desktop.
// 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