【问题标题】:Sequelize migration - run an array of queries in orderSequelize migration - 按顺序运行一系列查询
【发布时间】:2015-08-29 06:41:47
【问题描述】:

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

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)

【问题讨论】:

  • 它在什么方面不起作用?
  • 它不会按顺序执行查询。因此,例如,本应在较长查询之后运行的短查询(就执行速度而言)最终在较长查询完成之前运行。

标签: node.js sequelize.js


【解决方案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/ 强烈推荐!

【讨论】:

  • 首先,感谢您的回复。我在异步函数中遇到错误。我是否正确假设您正在使用 async 包并且 async 是一个var?
  • 异步函数是独立于异步包的东西。它们是 EcmaScript 2016 的一个功能。只有在使用 Babel 或 TypeScript 或其他东西进行转译时,才能使用它们。您会在我提供的链接中找到更好的描述:)
  • 如果您使用 io.js,那么您可以使用生成器而不是异步函数。这样,您就不需要转译。上面的链接中也对此进行了说明。
【解决方案2】:

我不完全知道您的代码有什么问题(如果有的话)。 你应该试试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
});

【讨论】:

  • 欢迎来到 SO。这实际上更像是一种评论,因为您实际上并不知道答案。答案应该不仅仅是关于如何调试问题的建议。
猜你喜欢
  • 1970-01-01
  • 2017-03-17
  • 2020-04-11
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
  • 2017-07-17
  • 1970-01-01
  • 2018-05-08
相关资源
最近更新 更多