Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

example: refactoring some code (in keystonejs) from "callback hell"-style to asynquence-style

View gist:8459026
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
var doQuery = function() {
count.exec(function(err, total) {
if (err) return sendError('database error', err);
query.exec(function(err, items) {
if (err) return sendError('database error', err);
sendResponse({
total: total,
items: items.map(function(i) {
return {
name: req.list.getDocumentName(i, true) || '(' + i.id + ')',
id: i.id
};
})
});
});
});
}
View gist:8459026
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
// [Update: this is the "old" way now, which sucks. see the next 2 files in this gist]
 
var doQuery = function() {
// fetch total
function fetchTotal(done){
count.exec(function(err, total) {
// note: `return` here does nothing for asynquence, only
// exits the function early. :)
if (err) return done.fail('database error', err);
done(total); // pass along `total` as a value-message
});
}
// fetch items
function fetchItems(done){
query.exec(function(err, items) {
// note: `return` here does nothing for asynquence, only
// exits the function early. :)
if (err) return done.fail('database error', err);
done(items); // pass along `items` as value-message
});
}
// transform the data to prepare it for `sendResponse()`
function prepareData(total, items){
return {
total: total,
items: items.map(function(i) {
return {
name: req.list.getDocumentName(i, true) || '(' + i.id + ')',
id: i.id
};
})
};
}
// behold, the elegant beauty of clean async flow-control
ASQ()
// fetch total and items in parallel
.gate(
fetchTotal,
fetchItems
)
// prepare data
.val(prepareData)
// now, send the transformed data along
.val(sendResponse)
// handle any errors that propagate up to here
.or(sendError);
}
View gist:8459026
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
// [Update: this now works!]
 
var doQuery = function() {
// fetch total
function fetchTotal(done){
count.exec(done.errfcb); // <-- Look ma, no code!
}
// fetch items
function fetchItems(done){
query.exec(done.errfcb); // <-- Look ma, no code!
}
// transform the data to prepare it for `sendResponse()`
function prepareData(total, items){
return {
total: total,
items: items.map(function(i) {
return {
name: req.list.getDocumentName(i, true) || '(' + i.id + ')',
id: i.id
};
})
};
}
// behold, the elegant beauty of clean async flow-control
ASQ()
// fetch total and items in parallel
.gate(
fetchTotal,
fetchItems
)
// prepare data
.val(prepareData)
// now, send the transformed data along
.val(sendResponse)
// handle any errors that propagate up to here
.or(sendError);
}
View gist:8459026
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
// [Update: even way better, this now works]
 
var doQuery = function() {
 
// transform the data to prepare it for `sendResponse()`
function prepareData(total, items){
return {
total: total,
items: items.map(function(i) {
return {
name: req.list.getDocumentName(i, true) || '(' + i.id + ')',
id: i.id
};
})
};
}
// behold, the elegant beauty of clean async flow-control
var sq = ASQ();
// fetch total and items in parallel
count.exec( sq.errfcb() );
query.exec( sq.errfcb() );
 
sq
// prepare data
.val(prepareData)
// now, send the transformed data along
.val(sendResponse)
// handle any errors that propagate up to here
.or(sendError);
}

While we're discussing promises, here is how I'd do this with promises.

var api = Promise.promisifyAll({count:count,query:query}); //convert our API to promises

var count = api.count(); // calls for eventual values are as simple as normal API calls
var exec = api.exec(); // there is no cruft here :)
var items = count.map(function(i){ // map the count
      return { id: i.id, name: req.list.getDocumentName(i, true) || "(" + i.id +")" };
});
Promise.all(count,items).then(function(c,i){ // all ready
    return count.map(function(){
        return { total: c, items: i};
    });
}).then(sendResponse).catch(sendError);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.