Sequelize migration - 按顺序运行一系列查询

时间:2015-08-28 21:17:02

标签: node.js sequelize.js

我有一系列需要按特定顺序运行的查询。我一直在尝试这个:

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();

这不符合预期。有什么建议吗?

更新:在回调中使用递归似乎可以正常工作

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 个答案:

答案 0 :(得分:1)

如果您使用io.js并且可以编写生成器,或者使用Babel或TypeScript进行转换并且可以编写异步函数,那么这就变得非常容易。

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) {
  // ...
})

注意:上面使用的async关键字是JavaScript EcmaScript 2016的原生功能,不要与“异步”npm模块混淆,这是完全不同的事情。

无论如何,这个解决方案确保一个查询在前一个查询结束之前不会启动,并且将按原始数组的顺序进行。它基本上就像读取一样。如果您可以编写生成器但不能编写异步函数,则可以使用生成器完成几乎相同的操作,但需要使用co()Bluebird.coroutine()等库。

查看这篇优秀文章,了解这些技术的背景知识。它们确实是JavaScript的未来:

https://blog.risingstack.com/asynchronous-javascript/&lt; - 强烈推荐!

答案 1 :(得分:0)

我并不完全知道您的代码存在什么问题(如果有的话)。 您应该尝试使用each function of the async lib

例如:

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