1

I have a series of queries that need to run in a specific order. I've been trying this:

var queries = []
queries.push('update blah set foo="bar"')
queries.push('update baz set bar="foo"')

for(var i=0; i< queries.length; i++){
  Promise.all([
    migration.sequelize.query(queries[i]).then(function(result){
      console.log(result)
    })
  ])
}
done();

This does not work as anticipated. Any suggestions?

UPDATE: using recursion in the callback seems to work

var queries = []
queries.push('update blah set foo="bar"')
queries.push('update baz set bar="foo"')

var index = 0
var execute = function(queries){
  if(typeof queries[index] == 'undefined'){
    return done()
  }
  console.log(queries[index])
  migration.sequelize.query(queries[index]).then(function(result){
    console.log(result)
    index += 1
    return execute(queries)
  })
}
execute(queries)
2
  • In what way isn't it working? Commented Aug 28, 2015 at 21:18
  • It doesn't execute the queries in order. So, for example, a short query (in terms of execution speed) that was supposed to run after a longer query ends up running before the longer one has finished. Commented Aug 28, 2015 at 21:24

2 Answers 2

1

If you're on io.js and can write generators, or transpiling using Babel or TypeScript and can write async functions, this becomes very easy.

async function runSerialQueries(queries) {
  var results = [];
  for (var i=0; i<queries.length; i++) {
    var query = queries[i];
    var result = await migration.sequelize.query(query);
    results.push(result);
  }
  return results;
}

runSerialQueries([
  'update blah set foo="bar"',
  'update baz set bar="foo"'
]).then(function(results) {
  // ...
})

NOTE: The async keyword used above is a native feature of JavaScript EcmaScript 2016, not to be confused with the "async" npm module which is a completely different thing.

Anyhow, this solution ensures that one query doesn't start until the previous one ends, and will go in the order of the original array. It basically behaves just like it reads. If you can write generators but not async functions, something nearly identical can be done with generators, but requires a library like co() or Bluebird.coroutine().

Check out this excellent article for background on these techniques. They really are the future of JavaScript:

https://blog.risingstack.com/asynchronous-javascript/ <-- highly recommended!

Sign up to request clarification or add additional context in comments.

3 Comments

First, thanks for the response. I'm getting an error at async function. Am I right to assume you're using the async package and async is a var?
Async function are a separate thing from the async package. They're a feature of EcmaScript 2016. You can only use them if you're transpiling using Babel or TypeScript or something. You'll find a much better description in the link I provided :)
If you're on io.js, then you could use generators instead of async functions. That way, you don't need to transpile. This is also explained in the above link.
0

I don't exactly know what the problem is with your code (if there any). You should try with the each function of the async lib.

For example:

async.each(queries, function(query, done) {
  // do the query here
  done(); // this query is done, so runs the next one
});

1 Comment

Welcome to SO. This is really more of a comment, since you don't actually know the answer. Answers should be more that suggestions of how to debug a problem.

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.