Skip to content

Instantly share code, notes, and snippets.

@getify
Last active August 9, 2020 04:09
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save getify/8459026 to your computer and use it in GitHub Desktop.
Save getify/8459026 to your computer and use it in GitHub Desktop.
example: refactoring some code (in keystonejs) from "callback hell"-style to asynquence-style
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
};
})
});
});
});
}
// [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);
}
// [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);
}
// [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);
}
@ClarkMiaguo
Copy link

@gerify regarding gistfile4.js This should not work.
var sq = ASQ();

// fetch total and items in parallel
count.exec( sq.errfcb() );
query.exec( sq.errfcb() );

sq
// prepare data

.val(prepareData) // then only query result

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment