我有一系列需要按特定顺序运行的查询。我一直在尝试这个:
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)
答案 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
});