then-utils v1.6.0
then-utils
A collection of useful, promise-returing utilities. No dependencies (other then Node builtins).
Utilities
All utilities return Promise
s.
callWithPromiseOrCallback
Arguments
func
- the function to call...args
- extra arguments to pass to the function
Description
Calls the given func
with optional extra ...args
, and a Node-style callback (error, data). If the function returns a Promise
, then it attaches it's resolve
and reject
to that Promise
. If the callback is called, then it will reject
if error
is given, or resolve
with the given data
.
Usage
const { callWithPromiseOrCallback } = require('then-utils');
const { addWithCallback, addWithPromise } = require('some-math-package');
callWithPromiseOrCallback(addWithCallback, 1, 2).then((result) => {
console.log(result); // 3
}).catch((error) => {
console.log('Oh no! Something blew up!');
console.log(error.stack);
});
callWithPromiseOrCallback(addWithPromise, 3, 4).then((result) => {
console.log(result); // 7
}).catch((error) => {
console.log('What?! Math errors?');
console.log(error.stack);
});
returnPromiseOrCallback
Arguments
callbackArg
- the callback argumenthandler
- thePromise
handler
Description
This function is mainly for API developers who still need to support callbacks but want to migrate to Promise
s. The callbackArg
should be whatever your callback argument is in your function. If the callbackArg
is a function, then it is called as a Node-style callback (error, data) when you resolve
or reject
in the handler
. Otherwise, it returns a Promise
with the given handler
.
Usage
const { returnPromiseOrCallback } = require('then-utils');
function myAPI(someArgs, myOptionalCallback) {
return returnPromiseOrCallback(myOptionalCallback, (resolve, reject) => {
console.log('process some arguments:', someArgs);
// process someArgs
resolve();
});
}
myAPI('Wow', (error) => {
if (error) return console.error('Oh no!', error.stack);
console.log('done processing it already? wow.');
});
myAPI('Cool').then(() => {
console.log('done processing it already? ok then!');
}).catch((error) => {
console.error('Aw man!', error.stack);
});
asyncFor
Arguments
arrOrObjOrNum
- an array, object, or number to loop ononloop
- a function called for every iteration of the loop
Description
TL;DR, just see the usage below
Asynchronously loops using setImmediate
. If arrOrObjOrNum
is a number, it'll be converted into an array by pushing null
into an array arrOrObjOrNum
times, and looping on that. It uses Object.keys()
to get the keys to loop through, except that if the key can be parsed to a Number
(with parseInt()
) then it'll convert it to a Number
. It'll call onloop
for every iteration of the loop with the current key (or index, for an array), the item at that position (null
if arrOrObjOrNum
is a number), and a breakLoop function (to exit the loop early). If onloop
returns a Promise
, it'll wait until the Promise
is resolve
d to goto the next loop. If the Promise
is reject
ed, it'll stop looping and reject it's own Promise
. Otherwise, it'll add a Node-style callback (error, data) argument to onloop
's arguments, where if given an error, it'll act as if it were reject
ed and end the loop.
Usage
const { asyncFor } = require('then-utils');
const myArray = [9, 3, 4];
const myObject = {
nom: 'hi',
foo: 8
};
asyncFor(myArray, (index, item) => {
return new Promise((resolve, reject) => {
console.log('index:', index);
console.log('item:', item);
resolve();
});
}).then(() => {
console.log('Wow, done!');
}).catch((err) => {
console.error(err.stack);
});
asyncFor(4, (index, item) => {
return new Promise((resolve, reject) => {
console.log('index:', index);
console.log('item:', item); // will always be null, since you passed a number, which means you just want to loop 4 times
resolve();
});
}); // then, catch handlers here...
asyncFor(myObject, (key, item) => {
return new Promise((resolve, reject) => {
console.log('key:', key);
console.log('item:', item);
resolve();
});
}); // then, catch handlers here...
asyncFor(myArray, (index, item, breakLoop, cb) => {
// you can also just use a callback instead of returning a Promise
console.log('index:', index);
console.log('item:', item);
cb();
}); // then, catch handlers here...
asyncFor(myArray, (index, item, breakLoop) => {
return new Promise((resolve, reject) => {
if (index === 1) {
return breakLoop(); // equivalent of `break`
}
// you must call `resolve` (or the callback) when you are done
// it can also act as `continue` if you `return resolve()` before you're finished
resolve();
});
});
rmrf
Arguments
pathname
- the path to remove recursively (can be a folder or a file)
Description
Remove a file or folder from the specified pathname
. If the path is a folder, it is removed recursively. If the file or folder isn't found, then it will resolve
, since the goal (having the path not exist) is already achieved.
Usage
const { rmrf } = require('then-utils');
rmrf('some-path/i-wanna/delete').then(() => {
console.log('great, done deleting the path');
}).catch((err) => {
console.error('crap, something went wrong while deleting the path');
console.error(err.stack);
});
mkdirp
Arguments
pathname
- the full path for the new folder
Description
Creates a folder at the specified path recursively, that is, it will create any folders that don't exist in the path.
Usage
const { mkdirp } = require('then-utils');
mkdirp('/i-exist/me-too/but-i-dont/me-neither/i-am-the-target-folder').then(() => {
console.log('the whole path now exists, yeah!');
}).catch((err) => {
conosle.error('oh man...');
console.error(err.stack);
});
filterByExtension
Arguments
pathname
- the path search in to filter it's filesext
- the extension to filter for
Description
Reads the files of the pathname
, and filters them. If their extension matches the specified ext
, then they will be returned.
Usage
const { filterByExtension } = require('then-utils');
filterByExtension('/path/i-want/to/search', '.js').then((files) => {
console.log('now i have a list of all the files ending with \'.js\':');
console.dir(files);
}).catch((err) => {
console.error('what happened?');
console.error(err.stack);
});
writeFile
Arguments
See fs.writeFile
.
Description
Promise
-ified fs.writeFile
.
Usage
const { writeFile } = require('then-utils');
writeFile('/my/file/path', 'some file contents').then(() => {
console.log('done writing file');
}).catch((err) => {
console.error('crap');
console.error(err.stack);
});
exec
Arguments
See child_process.exec
.
Description
Promise
-ified child_process.exec
.
Usage
const { exec } = require('then-utils');
exec('ls $HOME', {
env: {
HOME: '/home/my-place'
}
}).then(({ stdout, stderr }) => {
console.log('done executing command');
console.log(stdout);
console.log(stderr);
}).catch((err) => {
console.error('why?!');
console.error(err.stack);
});
mv
Arguments
See fs.rename
.
Description
Promise
-ified fs.rename
.
Usage
const { mv } = require('then-utils');
mv('/my/old/path', '/my/new/place').then(() => {
console.log('done moving path');
}).catch((err) => {
console.error('go away errors, i don\'t like you');
console.error(err.stack);
});
cpr
Arguments
frompath
- the path to copy fromtopath
- the path to copy to
Description
Copies a folder or file recursively from frompath
to topath
.
Usage
const { cpr } = require('then-utils');
cpr('/some/folder', '/put/me/here').then(() => {
console.log('done copying folder');
}).catch((err) => {
console.error('ugh errors');
console.error(err.stack);
});
parseArgs
Arguments
args
- the arguments to parse
Description
Parses the given arguments into an object. I'm not going to spend time explaining this, just take the example.
Usage
const { parseArgs } = require('then-utils');
parseArgs(process.argv.slice(2)).then((args) => {
// let's say process.argv.slice(2) === ['--hi', '--foo', '8', '-u']
// then `args` would contain:
args.hi === true;
args.foo === '8';
args.u === true;
}).catch((err) => {
console.error('nope, i\'m not even gonna log this one');
});
spawn
Arguments
See child_process.spawn
.
Description
Promise
-ified child_process.spawn
.
Usage
const { spawn } = require('then-utils');
const child = spawn('ls', ['$HOME'], {
env: {
HOME: '/home/my-place'
}
});
child.cmd; // contains the spawned ChildProcess
child.then(() => {
console.log('done executing this other command');
}).catch((err) => {
console.error('well, i can\'t do anything about errors');
console.error(err.stack);
});
sleep
Arguments
ms
- number of milliseconds to wait
Description
A "sleep" function (a.k.a. setTimeout
), resolve
s after the given time is up.
Usage
const { sleep } = require('then-utils');
sleep(800).then(() => {
console.log('800 milliseconds are up');
});
readFile
Arguments
See fs.readFile
.
Description
Promise
-ified fs.readFile
.
Usage
const { readFile } = require('then-utils');
readFile('/my/file/path/to/read').then((cont) => {
console.log('done reading file');
console.log('file buffer:', cont);
}).catch((err) => {
console.error('no, i... *sigh*');
console.error(err.stack);
});