Last active
February 10, 2017 14:21
-
-
Save elmigranto/f5a5beaf8426a62565e8e7ed0cf5fb4a to your computer and use it in GitHub Desktop.
awaitability
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
'use strict'; | |
// awaitable(fn, [arg1, [arg2[, ..., argN]]]) | |
// Always returns array of results. | |
const awaitableSpread = (fn, ...args) => { | |
if (typeof fn !== 'function') | |
throw new Error(`awaitable() needs a function as first argument, got "${typeof func}"`); | |
return new Promise((resolve, reject) => { | |
fn.call(null, ...args, (err, ...results) => { | |
return err | |
? reject(err) | |
: resolve(results); | |
}); | |
}); | |
}; | |
// Same as awaitableSpread() except always returns first result. | |
const awaitable = async (...everything) => (await awaitableSpread(...everything))[0]; | |
module.exports = awaitable; | |
module.exports.spread = awaitableSpread; |
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
'use strict'; | |
const fs = require('fs'); | |
const dns = require('dns'); | |
const awaitable = require('../src/awaitable'); | |
const main = async () => { | |
// Use awaitabale() when: | |
// - callback() is invoked with single argument; | |
// - or you only interested in the first argument anyways. | |
const stat = await awaitable(fs.stat, __filename); | |
const address = await awaitable(dns.lookup, 'localhost'); | |
// Here's an example of how to pass multiple arguments | |
// and access multiple callback() arguments using destructuring. | |
const source = await awaitable(fs.readFile, __filename, 'utf8'); | |
const [address6, family6] = await awaitable.spread(dns.lookup, 'localhost', 6); | |
console.log({ // eslint-disable-line no-console | |
stat, | |
source, | |
address, | |
address6, family6 | |
}); | |
}; | |
if (!module.parent) | |
main(); |
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
'use strict'; | |
const awaitable = require('../src/awaitable'); | |
describe('awaitable()', () => { | |
it('awaitable.spread(fn)', async () => { | |
const callbackApi = (cb) => setImmediate(cb); | |
await awaitable.spread(callbackApi); | |
}); | |
it('awaitable.spread(fn, oneArg)', async () => { | |
const callbackApi = (x, cb) => setImmediate(cb, null, x); | |
const result = await awaitable.spread(callbackApi, 1); | |
expect(result).to.eql([1]); | |
}); | |
it('awaitable.spread(fn, multiple, argu, ments)', async () => { | |
const callbackApi = (x, y, z, cb) => setImmediate(cb, null, x, y, z); | |
const result = await awaitable.spread(callbackApi, 1, 2, 3); | |
expect(result).to.eql([1, 2, 3]); | |
}); | |
it('awaitable.spread(non-function) throws', () => { | |
expect(() => awaitable.spread(42)).to.throw(/needs a function/); | |
}); | |
describe('awaitable() always returns first argument', () => { | |
const callbackApi = (...args) => setImmediate(args[args.length - 1], null, ...args.slice(0, -1)); | |
it('no arguments', async () => { | |
expect(await awaitable(callbackApi)).to.equal(undefined); | |
}); | |
it('single argument', async () => { | |
expect(await awaitable(callbackApi, 1)).to.equal(1); | |
}); | |
it('multiple arguments', async () => { | |
expect(await awaitable(callbackApi, ...[1, 2, 3])).to.equal(1); | |
}); | |
}); | |
describe('awaitable.spread() always returns array', () => { | |
const callbackApi = (...args) => setImmediate(args[args.length - 1], null, ...args.slice(0, -1)); | |
it('no arguments', async () => { | |
expect(await awaitable.spread(callbackApi)).to.eql([]); | |
}); | |
it('single argument', async () => { | |
expect(await awaitable.spread(callbackApi, ...[1])).to.eql([1]); | |
}); | |
it('multiple arguments', async () => { | |
expect(await awaitable.spread(callbackApi, ...[1, 2, 3])).to.eql([1, 2, 3]); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment