2

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);
    }
  }  
}
4
  • 2
    Which database library are you using? Why do you want it to be synchronous? Commented Jul 7, 2015 at 21:55
  • "I'd like to perform synchronous queries" This is usually not possible. promises would not make them synchronous either. Commented Jul 7, 2015 at 21:57
  • Use a synchronous programming language then... Commented Jul 7, 2015 at 22:09
  • I edited my question, my point wasn't clear Commented Jul 8, 2015 at 9:12

2 Answers 2

2

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();
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

yeah I think that's a viable solution to my problem (I updated the question)
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.