diff --git a/README.md b/README.md index 3437cf8..d5964d1 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,21 @@ Here is an example of `this.MULTI()` in action (repeated from the overview): } ); + You can identify the results of a function by passing a result identifier to MULTI. The results of a function can retrieved using this key in the final step. The result will be a single value if callback receives 0 or 1 argument, otherwise it will be an array of arguments passed to the callback. + + Example: + + flow.exec( + function() { + dbGet('userIdOf:bobvance', this.MULTI('bob')); + dbGet('userIdOf:joohndoe', this.MULTI('john')); + },function(results) { + dbSet('user:' + results['bob'] + ':email', 'bobvance@potato.egg'); + dbSet('user:' + results['john'] + ':email', 'joohndoe@potato.egg'); + okWeAreDone(); + } + ); + In many cases, you may simply discard the arguments passed to each of the callbacks generated by `this.MULTI()`, but if you need them, they are accessible as an array of `arguments` objects passed as the first argument of the next function. Each `arguments` object will be diff --git a/examples/keystore.js b/examples/keystore.js index fee19bf..3adf2c9 100644 --- a/examples/keystore.js +++ b/examples/keystore.js @@ -31,6 +31,14 @@ exports.get = function(key, callback) { }, 100); } +// keystore.exists(key, callback) +// callback signature: (value) +exports.exists = function(key, callback) { + setTimeout(function() { + if (callback) callback(key in db); + }, 100); +} + // keystore.increment(key, incrementBy, callback) // callback signature: (error, newValue) exports.increment = function(key, incrementBy, callback) { diff --git a/flow.js b/flow.js index 771c8da..9d92de0 100644 --- a/flow.js +++ b/flow.js @@ -58,11 +58,17 @@ // MULTI can be used to generate callbacks that must ALL be called before the next step // in the flow is executed. Arguments to those callbacks are accumulated, and an array of // of those arguments objects is sent as the one argument to the next step in the flow. - flowState.MULTI = function() { + // @param {String} resultId An identifier to get the result of a multi call. + flowState.MULTI = function(resultId) { flowState.__multiCount += 1; return function() { flowState.__multiCount -= 1; flowState.__multiOutputs.push(arguments); + + if (resultId) { + var result = arguments.length <= 1 ? arguments[0] : arguments + flowState.__multiOutputs[resultId] = result; + } if (flowState.__multiCount === 0) { var multiOutputs = flowState.__multiOutputs; diff --git a/tests.js b/tests.js index f6395f2..019a0fe 100644 --- a/tests.js +++ b/tests.js @@ -4,7 +4,7 @@ var keystore = require('./examples/keystore'); var flowsComplete = 0; setTimeout(function() { - var expected = 3; + var expected = 5; assert.strictEqual(flowsComplete, expected, flowsComplete + "/" + expected +" flows finished"); }, 1000); @@ -34,6 +34,35 @@ flow.exec( } ); +// MULTI with result identifier test +flow.exec( + function() { + var db = keystore.getDb(); + db['firstName'] = "Bob" + db['lastName'] = "Vance" + keystore.get("firstName", this.MULTI('first-name')); + keystore.get("lastName", this.MULTI('last-name')); + },function(results) { + assert.strictEqual(results['first-name'][1], "Bob", "multi with result identifier test didn't work"); + assert.strictEqual(results['last-name'][1], "Vance", "multi with result identifier test didn't work"); + flowsComplete += 1; + } +); + +// MULTI with result identifier for single return value test +flow.exec( + function() { + var db = keystore.getDb(); + db['bob'] = "Bob Vance" + keystore.exists("bob", this.MULTI('bob-exists')); + keystore.exists("john", this.MULTI('john-exists')); + },function(results) { + assert.strictEqual(results['bob-exists'], true, "multi with result identifier for single return value test didn't work"); + assert.strictEqual(results['john-exists'], false, "multi with result identifier for single return value test didn't work"); + flowsComplete += 1; + } +); + // serialForEach test var valueSequence = []; flow.serialForEach([1, 2, 3, 4], function(val) {