Reputation: 1555
I'd like to perform queries in order but I don't know what is the best approach.
Let's say I'd like to do the following :
if (name) {
//first query
db.query({name:name}).exec(function(err,result) {
//save result
})
}
if (isEmpty(result)) {
//make another query
db.query({anotherField:value}).exec(function(err,result) {
//save result
})
}
Should I use promises on that case?
That would be an example with cakePHP :
if (!isset($field1)) {
$result = $this->item->find( ... conditions => ... = $field2);
} else {
if (!isset($field2)) {
$result = $this->item->find( ... conditions => ... = $field1);
} else {
$result = $this->item->find( ... conditions => ... = $field1 && ... =$field2);
if (empty($result)) {
$result = $this->item->find( ... conditions => ... =$field2);
}
}
}
Upvotes: 2
Views: 790
Reputation: 11052
If you mean "in order" you can nest the callbacks. Passing callbacks is the classic (non-promise) way to structure asynchronous code:
function doMultipleAsyncThings(name, callback){
if (name) {
//first query
db.query({name:name}).exec(function(err,result) {
if (isEmpty(result)) {
//make another query
db.query({anotherField:value}).exec(function(err,result) {
//save result
})
} else {
//save result
}
})
} else {
return callback('no name');
}
}
Heads up, after more than 2 or so operations, you end up in 'callback hell' with 100+ lines of nested code, the async library is helpful for this:
var async = require('async');
doMultipleAsyncThings('plato', function(){
console.log(arguments)
});
function doMultipleAsyncThings(name, callback){
// `callback` is a passed-in function to call after doMultipleAsyncThings is done
// Here, it is the function we passed in above after 'plato'
async.waterfall([function(done){
done(null, name);
},
firstQuery,
secondQuery,
], callback)
}
function firstQuery(name, done){
if (name) {
// You can define and pass a callback inline:
db.query({name:name}).exec(function(err,result) {
done(err, result);
})
} else {
done('no name');
}
}
function secondQuery(result, done){
if (isEmpty(result)) {
// You can pass a callback by reference:
db.query({anotherField:value}).exec(done)
} else {
//save result
done();
}
}
Upvotes: 2
Reputation: 2951
Promises would be a good fit for this, the q
library is the most common for this. You probably just want to nest your promises like so:
var q = require('q');
if (name) {
//first query
q.ninvoke(db.query({name:name}), 'exec')
.then(function(result) {
//save result
if (isEmpty(result)) {
//make another query
q.ninvoke(db.query({anotherField:value}), 'exec')
.then(function(result) {
//save result
})
.fail(function(err) {
//handle failure
console.error(err, err.stack);
});
}
})
.fail(function(err) {
//handle failure
console.error(err, err.stack);
});
}
q.ninvoke
allows us to convert standard nodejs functions into their promise equivalent.
Upvotes: 2