Skip to content

Instantly share code, notes, and snippets.

@mgcam
Last active March 22, 2016 15:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgcam/bbe70e7e805a78a1c5d0 to your computer and use it in GitHub Desktop.
Save mgcam/bbe70e7e805a78a1c5d0 to your computer and use it in GitHub Desktop.
analogue of bash 'set -o pipefail' for Node.js pipeline of async processes (implemented via promises)
#!/usr/bin/env node
// Tested with Node.js v4.3.2
"use strict";
const spawn = require('child_process').spawn;
function createPromise(p) {
return new Promise(
function(resolve, reject) {
p.on('close', function(code, signal) {
if (code || signal) {
reject(code || signal);
} else {
resolve();
}
});
p.on('error', function(err) {
reject(err);
});
p.stdin.on('error', (err) => {
reject(err);
});
p.stdout.on('error', (err) => {
reject(err);
});
}
);
}
function testProcessPromise(f) {
const cat = spawn('cat', [f]);
cat.title = 'cat';
const wc = spawn('wc', ['-l']);
wc.title = 'wc';
var prs = [cat, wc];
var promises = prs.map(function(process) {return createPromise(process); });
var numProcesses = prs.length;
for (var i = 0; i < numProcesses; i++) {
var title = prs[i].title;
promises[i].then(
// Report success
function() {
console.log('SUCCESS ' + title);
}
)
.catch(
// Log the rejection reason
function(code) {
console.log('ERROR ' + title + ' ' + code);
}
);
}
Promise.all(promises).then(function() {console.log('ALL GOOD');},
function() {console.log('SOMETHING FAILED');}
);
// Pipeline data flow definition - analogue of 'cat FILE | wc -l'
// and a request to start on next tick.
process.nextTick(() => {
cat.stdout.pipe(wc.stdin);
wc.stdout.pipe(process.stdout);
});
}
testProcessPromise('CHANGES'); // Call for a file that exists
testProcessPromise('dodo'); // Call for a file that does not exist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment