From de541568241af7e520e936e16e7e7478d0579149 Mon Sep 17 00:00:00 2001 From: Jamie Dixon Date: Sun, 24 May 2020 17:48:54 +0100 Subject: [PATCH 1/2] Allow fn passed to Async.fromNode to be partially applied --- src/Async/Async.spec.js | 15 +++++++++++++++ src/Async/index.js | 12 ++++++++++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/Async/Async.spec.js b/src/Async/Async.spec.js index 4f963472f..8830622dd 100644 --- a/src/Async/Async.spec.js +++ b/src/Async/Async.spec.js @@ -225,6 +225,21 @@ test('Async fromNode resolution', t => { Async.fromNode(resCPS)(val).fork(rej(val), res(val)) }) +test('Async fromNode partially applied', t => { + t.plan(2) + + const val = 'super fun' + + const rejCPS = (x, y, cf) => cf(x, y) + const resCPS = (x, y, cf) => cf(null, x, y) + + const rej = y => x => t.equal(x, y, 'rejects an erred CPS') + const res = y => x => t.equal(x, y, 'resolves a good CPS') + + Async.fromNode(rejCPS)(val)(val).fork(rej(val), res(val)) + Async.fromNode(resCPS)(val)(val).fork(rej(val), res(val)) +}) + test('Async all', t => { const all = bindFunc(Async.all) diff --git a/src/Async/index.js b/src/Async/index.js index d902de6d4..f72bd2a04 100644 --- a/src/Async/index.js +++ b/src/Async/index.js @@ -48,14 +48,22 @@ function fromNode(fn, ctx) { throw new TypeError('Async.fromNode: CPS function required') } - return (...args) => - Async((reject, resolve) => { + const _fn = curry(fn) + + return (...args) => { + + if (args.length < _fn.length - 1) { + return fromNode(_fn(...args), ctx) + } + + return Async((reject, resolve) => { fn.apply(ctx, args.concat( (err, data) => err ? reject(err) : resolve(data) ) ) }) + } } function fromPromise(fn) { From 030c299f2aa1d910f2f0bf7f941a33199efe5a60 Mon Sep 17 00:00:00 2001 From: Jamie Dixon Date: Wed, 27 May 2020 20:08:10 +0100 Subject: [PATCH 2/2] Document changes to fromNode that allow the return fn to be partially applied in some cases --- docs/src/pages/docs/crocks/Async.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/src/pages/docs/crocks/Async.md b/docs/src/pages/docs/crocks/Async.md index 3a9173bd7..9606b7e39 100644 --- a/docs/src/pages/docs/crocks/Async.md +++ b/docs/src/pages/docs/crocks/Async.md @@ -379,8 +379,17 @@ As such, the need for binding may arise. `fromNode` provides a second, optional argument that takes the context that will be used to bind the function being wrapped. -Any curried interface will not be respected and if a curried interface is needed -then [`nAry`][nary] can be used. +The function returned from `fromNode` will be automatically curried, allowing you +to partially apply the function up to its penultimate parameter[1], so long as the +arity of the original function given to `fromNode` can be determined via its `.length` property. + +In practice this means that functions defined via `compose` or those making use +of `arguments`, spread args (`...args`) or default values for parameters, will not be +good candidates for partial application. + +[1] The final parameter to the incoming function is provided to you by`fromNode` rather +than being part of the parameters that can be partially applied. +