Skip to content

Instantly share code, notes, and snippets.

@pmuellr
Created February 5, 2016 07:16
Show Gist options
  • Save pmuellr/583aacfb73f664c4ac12 to your computer and use it in GitHub Desktop.
Save pmuellr/583aacfb73f664c4ac12 to your computer and use it in GitHub Desktop.
a class to help deal with multiple async fn's
'use strict'
const fs = require('fs')
class Steps {
constructor (tx) {
this.tx = tx
this.steps = []
this.runningSeries = false
this.runningParallel = false
}
add (step) {
if (this.runningSeries) throw new Error('running series')
if (this.runningParallel) throw new Error('running parallel')
this.steps.push(step)
return this
}
series (cb) {
if (this.runningParallel) throw new Error('running parallel')
this.runningSeries = true
if (this.steps.length === 0) return process.nextTick(cb, this.tx)
const step = this.steps.shift()
const done = _ => this.series(cb)
const stop = _ => process.nextTick(cb, this.tx)
step({tx: this.tx, done: done, stop: stop})
}
parallel (cb) {
if (this.runningSeries) throw new Error('running series')
this.runningParallel = true
if (this.steps.length === 0) return process.nextTick(cb, this.tx)
let remaining = this.steps.length
this.steps.forEach(step => {
const done = _ => {
remaining--
if (remaining === 0) process.nextTick(cb, this.tx)
}
const stop = _ => {
throw Error(`stop() not valid in parallel`)
}
step({tx: this.tx, done: done, stop: stop})
})
}
}
// ============================================================================
steps1()
function steps1() {
console.log('steps1:')
new Steps()
.add(s => wait(1, s.done))
.add(s => wait(2, s.done))
.add(s => wait(1, s.done))
.series(steps2)
}
function steps2() {
console.log('steps2:')
new Steps()
.add(s => wait(1, s.done))
.add(s => wait(2, s.done))
.add(s => wait(1, s.done))
.parallel(steps3)
}
function steps3() {
const tx = []
console.log('steps3:')
new Steps(tx)
.add(stepA)
.add(stepB)
.add(stepC)
.parallel(tx => {
console.log(' ' + tx.join(', '))
steps4()
})
function stepA(s) { s.tx.push('stepA'); s.done() }
function stepB(s) { s.tx.push('stepB'); s.done() }
function stepC(s) { s.tx.push('stepC'); s.done() }
}
function steps4() {
const tx = []
console.log('steps4:')
new Steps(tx)
.add(stepA)
.add(stepB)
.add(stepC)
.series(tx => {
console.log(' ' + tx.join(', '))
steps5()
})
function stepA(s) { s.tx.push('stepA'); s.done() }
function stepB(s) { s.tx.push('stepB'); s.stop() }
function stepC(s) { s.tx.push('stepC'); s.done() }
}
function steps5() {
const tx = []
console.log('steps5:')
new Steps(tx)
.add(stepA)
.add(stepA)
.add(stepA)
.series(tx => {
console.log(' ' + JSON.stringify(tx))
stepsEnd()
})
function stepA(s) {
fs.readFile(__filename, (err, data) => {
s.tx.push([err, data.length])
s.done()
})
}
}
function stepsEnd() {
console.log('done')
}
function add(x, y, cb) {
process.nextTick(cb, x + y)
}
function wait(secs, cb) {
console.log(` wait->${secs}`)
setTimeout(cbWait, secs * 1000)
function cbWait() {
console.log(` wait<-${secs}`)
cb()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment