A comparison of async to qryq in specifying a compound query that is diamond-shaped. http://bguiz.com/post/64567226287/a-sneak-peek-from-my-talk-about-qryq-at-osdc-2013
var async = require('async'); | |
var _ = require('underscore'); | |
var api = { | |
add: function(qry, callback) { | |
if (!qry || ! _.isNumber(qry.a) || ! _.isNumber(qry.b)) { | |
callback('Must specify two numeric params, a and b. Params were: '+JSON.stringify(qry), null); | |
} | |
else { | |
callback(null, qry.a + qry.b); | |
} | |
}, | |
multiply: function(qry, callback) { | |
if (!qry || ! _.isNumber(qry.a) || ! _.isNumber(qry.b)) { | |
callback('Must specify two numeric params, a and b. Params were: '+JSON.stringify(qry), null); | |
} | |
else { | |
callback(null, qry.a * qry.b); | |
} | |
} | |
}; | |
async.waterfall([ | |
function(callback) { | |
callback(null, {a: 3, b: 4}); | |
}, | |
api.add, | |
function(result1, callback) { | |
async.parallel([ | |
function(cb) { | |
api.multiply({a: result1, b: 3}, cb); | |
}, | |
function(cb) { | |
api.multiply({a: 7, b: result1}, cb); | |
} | |
], | |
function(err, parallelResult) { | |
callback(null, {a: parallelResult[0], b: parallelResult[1]}); | |
}); | |
}, | |
api.add | |
], | |
function(err, diamondResult) { | |
console.log('diamondResult:', diamondResult); | |
}); | |
/* | |
Notes: | |
- with async there is a need to use wrapper function whener parsing is necessary | |
- also to pass in the initial value | |
- with async, the syntax is a lot more verbose | |
- still need to think of how to "wire up" the function together by knowing their implementation | |
- not fully declarative | |
*/ |
var qryq = require('./qryq'); | |
var _ = require('underscore'); | |
var Q = require('q'); | |
var api = { | |
add: function(deferred, qry) { | |
if (!qry || ! _.isNumber(qry.a) || ! _.isNumber(qry.b)) { | |
deferred.reject('Must specify two numeric params, a and b. Params were: '+JSON.stringify(qry)); | |
} | |
else { | |
deferred.resolve(qry.a + qry.b); | |
} | |
}, | |
multiply: function(deferred, qry) { | |
if (!qry || ! _.isNumber(qry.a) || ! _.isNumber(qry.b)) { | |
deferred.reject('Must specify two numeric params, a and b. Params were: '+JSON.stringify(qry)); | |
} | |
else { | |
deferred.resolve(qry.a * qry.b); | |
} | |
} | |
}; | |
var queryQueue = [ | |
{id: "A", api: "add", qry:{a:3, b:4}}, | |
{id: "B", api: "multiply", qry:{a:"#{A}", b:3}}, | |
{id: "C", api: "multiply", qry:{a:7, b: "#{A}"}}, | |
{id: "D", api: "add", qry:{a:"#{C}", b:"#{B}"}} | |
]; | |
var deferred = Q.defer(); | |
qryq.dependent(deferred, queryQueue, api); | |
deferred.promise.then(function(diamondResult) { | |
console.log('diamondResult:', JSON.stringify(diamondResult)); | |
var qryDsResult = _.findWhere(diamondResult, {id: 'D'}); | |
console.log('qryDsResult:', qryDsResult && qryDsResult.response && qryDsResult.response.value); | |
}); | |
/* | |
- no need to think about how to wire up functions together | |
- fully declarative | |
- infers order of execution | |
- infers which query depends upon the other | |
- return value differs in philosophy | |
- rather than return only the final result (like async#waterfall), returns all of them (like async#parallel) | |
- execution does not stop when an error is encountered at some point in the chain | |
- errors are verbose, and inline with each query | |
- heaps easier to find out where a compound query has gone wrong | |
- requires an additional dependency: Q for promises | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment