Comparing version 1.0.0 to 1.1.0
68
index.js
@@ -43,2 +43,70 @@ var acomb = module.exports = {}; | ||
acomb.spreadOptions = function spreadOptions(func, option1/*, option2...*/) { | ||
var options; | ||
if (Array.isArray(option1)) { | ||
options = option1; | ||
} else { | ||
options = _rest(arguments); | ||
} | ||
return function (obj, callback) { | ||
var newArgs = options.reduce(function(acc, key) { | ||
acc.push(obj[key]); | ||
return acc; | ||
}, []); | ||
newArgs.push(callback); | ||
func.apply(this, newArgs); | ||
}; | ||
}; | ||
acomb.before = function before(func, asyncBody) { | ||
return function (/* args..., callback */) { | ||
var args = _initial(arguments); | ||
var callback = _last(arguments); | ||
var result; | ||
try { | ||
result = func.apply(this, args); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
asyncBody.call(this, result, callback); | ||
}; | ||
}; | ||
acomb.after = function after(asyncBody, func) { | ||
return function (/* args..., callback */) { | ||
var args = _initial(arguments); | ||
var callback = _last(arguments); | ||
args.push(function newCb(err/*, results...*/) { | ||
if (err) { return callback(err); } | ||
var results = _rest(arguments); | ||
var result; | ||
try { | ||
result = func.apply(null, results); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
callback(null, result); | ||
}); | ||
asyncBody.apply(this, args); | ||
}; | ||
}; | ||
acomb.provided = function provided(predicate, func) { | ||
return function (/*args..., callback*/) { | ||
var args = _initial(arguments); | ||
var callback = _last(arguments); | ||
var result; | ||
try { | ||
result = predicate.apply(this, args); | ||
} catch (e) { | ||
return callback(e); | ||
} | ||
if (result) { | ||
return func.apply(this, arguments); | ||
} else { | ||
callback.apply(null, [null].concat(args)); | ||
} | ||
}; | ||
}; | ||
function _last(arr) { | ||
@@ -45,0 +113,0 @@ return arr[arr.length - 1]; |
{ | ||
"name": "acomb", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Higher-order utilities for use with async functions", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -1,2 +0,2 @@ | ||
# acomb [![Build Status via Travis CI](https://travis-ci.org/aearly/acomb.svg?branch=master)](https://travis-ci.org/aearly/acomb) [![NPM version](http://img.shields.io/npm/v/acomb.svg)](https://www.npmjs.org/package/acomb) | ||
# acomb [![Build Status via Travis CI](https://travis-ci.org/aearly/acomb.svg)](https://travis-ci.org/aearly/acomb) [![NPM version](http://img.shields.io/npm/v/acomb.svg)](https://www.npmjs.org/package/acomb) | ||
@@ -13,3 +13,8 @@ Higher-order utilities for use with async functions. | ||
* [partialRight](#partialRight) | ||
* [spreadOptions](#spreadOptions) | ||
* [before](#before) | ||
* [after](#after) | ||
* [provided](#provided) | ||
<a name="constant"> | ||
### constant(value) | ||
@@ -30,2 +35,3 @@ | ||
<a name="asyncify"> | ||
### asyncify(func) | ||
@@ -46,2 +52,4 @@ | ||
<a name="flip"> | ||
### flip(function) | ||
@@ -64,2 +72,4 @@ | ||
<a name="partialRight"> | ||
### partialRight(func, args...) | ||
@@ -77,1 +87,74 @@ | ||
``` | ||
<a name="spreadOptions"> | ||
### spreadOptions(func, option1, option2, ...) | ||
Takes a function of the form `function(object, callback) {}` and converts it to the form `function(option1, option2, ... callback) {}` based on the strings passed. The strings passed will pick properties from the object and turn them in to direct arguments. Useful in `async.auto` in conjunction with `flip` for destructuring the results. | ||
```js | ||
function doFoo(bar baz, callback) { | ||
// .... | ||
} | ||
async.auto({ | ||
bar: getBar, | ||
baz: getBaz | ||
foo: ["bar", "baz", acomb.flip(acomb.spreadOptions(doFoo, "bar", "baz"))], | ||
//... | ||
}, callback) | ||
``` | ||
<a name="before"> | ||
### before(func, asyncFunc) | ||
Run a synchronous function before an async function. The synchronous function will be called with the aguments passed (without the callback), and the async function will be called with the return value of the sync function. | ||
```js | ||
function trim (str) { return str.trim(); } | ||
async.waterfall([ | ||
getMessyInput, | ||
acomb.before(trim, function parseData(str, next) { | ||
// `str` has its whitespace trimmed | ||
//... | ||
}), | ||
//... | ||
], callback) | ||
``` | ||
<a name="after"> | ||
### after(asyncFunc, func) | ||
Run a synchronous function after an async function, with the results of the async function as arguments. The return value of the sync function will be passed to the original callback. | ||
```js | ||
var getTheDataIWant = acomb.after(getData, function (data) { | ||
return _.pick(data, ["foo", "bar", "baz"]) | ||
}); | ||
``` | ||
*note: If you want to run an async function before or after another, just use `async.seq` or `async.compose`* | ||
<a name="provided"> | ||
### provided(predicate, func) | ||
Conditionally run an async func based on the results of a predicate. The predicate function will be passed the same args as the async function. If the predicate returns false, the args will be passed to the async function's callback. | ||
```js | ||
async.map( | ||
sparseFilenames, | ||
acomb.provided(_.identity, acomb.partialRight(fs.readFile, "utf8")) | ||
function (err, results) { | ||
// results will be an array containing the data of the file names | ||
// that actually existed -- no errors due to invalid file names. | ||
} | ||
); | ||
``` | ||
## License | ||
MIT |
121
test.js
var a = require("./"); | ||
var assert = require("better-assert"); | ||
var noop = function () {}; | ||
@@ -32,3 +33,3 @@ | ||
assert(z === 3); | ||
})(1, 2, 3, function () {}); | ||
})(1, 2, 3, noop); | ||
}); | ||
@@ -57,3 +58,3 @@ | ||
done(); | ||
})(function () {}, 1, 2, 3); | ||
})(noop, 1, 2, 3); | ||
}); | ||
@@ -72,11 +73,119 @@ }); | ||
done(); | ||
}, 3, 4)(1, 2, function () {}); | ||
}, 3, 4)(1, 2, noop); | ||
}); | ||
}); | ||
/*describe("before", function () { | ||
describe("spreadOptions", function () { | ||
it("should spread options", function () { | ||
a.spreadOptions(function (x, y, cb) { | ||
assert(x === 1); | ||
assert(y === 2); | ||
assert(typeof cb === "function"); | ||
}, "x", "y")({x: 1, y: 2}, noop); | ||
}); | ||
it("should also work with an array arg", function () { | ||
a.spreadOptions(function (x, y, cb) { | ||
assert(x === 1); | ||
assert(y === 2); | ||
assert(typeof cb === "function"); | ||
}, ["x", "y"])({x: 1, y: 2}, noop); | ||
}); | ||
it("should work in conjunction with flip", function () { | ||
a.flip(a.spreadOptions(function (x, y, cb) { | ||
assert(x === 1); | ||
assert(y === 2); | ||
assert(typeof cb === "function"); | ||
}, ["x", "y"]))(noop, {x: 1, y: 2}); | ||
}); | ||
}); | ||
describe("before", function () { | ||
function add2(x) { return x + 2; } | ||
it("should run a function before another", function (done) { | ||
var f = a.before(func, body) | ||
var f = a.before(add2, function (y, callback) { | ||
callback(null, y); | ||
}); | ||
f(1, function (err, result) { | ||
assert(result === 3); | ||
done(); | ||
}); | ||
}); | ||
});*/ | ||
it("should catch errors in the before function", function (done) { | ||
a.before(function () { | ||
throw new Error("foo"); | ||
}, noop)("asdf", function (err) { | ||
assert(err.message === "foo"); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe("after", function () { | ||
function mul(x, y) { return x * y; } | ||
it("should run a function after", function (done) { | ||
var f = a.after(function(cb) { return cb(null, 4, 5); }, mul); | ||
f(function (err, result) { | ||
assert(result === 20); | ||
done(); | ||
}); | ||
}); | ||
it("should catch errors in the after function", function (done) { | ||
a.after( | ||
function (arg, cb) { return cb(null, arg); }, | ||
function () { | ||
throw new Error("foo"); | ||
})("asdf", function (err) { | ||
assert(err.message === "foo"); | ||
done(); | ||
}); | ||
}); | ||
it("should catch errors in the async function", function (done) { | ||
a.after( | ||
function (arg, cb) { return cb(new Error("foo")); }, | ||
noop)("asdf", function (err) { | ||
assert(err.message === "foo"); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe("provided", function () { | ||
it("should conditionally run an async function", function (done) { | ||
var f = a.provided( | ||
function (x, y) { | ||
assert(x === 1); | ||
assert(y === 2); | ||
return true; | ||
}, | ||
function (x, y, cb) { | ||
assert(x === 1); | ||
assert(y === 2); | ||
assert(typeof cb === "function"); | ||
done(); | ||
}); | ||
f(1, 2, noop); | ||
}); | ||
it("should conditionally run an async function (false)", function (done) { | ||
var f = a.provided(function () { return false; }, | ||
function () { | ||
throw new Error("shouldn't get here"); | ||
}); | ||
f(1, 2, function (err, x, y) { | ||
assert(!err); | ||
assert(x === 1); | ||
assert(y === 2); | ||
done(); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
14459
284
156