我用writeTransaction()
包装了一个函数Meteor._wrapAsync
,并在for
循环中调用它5次,该循环写了一个MySQL事务。
然而,从MySQL查询日志来看,似乎循环的下一次迭代是在前一个循环中的函数writeTransactionSync()
完成之前执行的。
如果Meteor._wrapAsync
没有使函数阻塞,我们如何使函数同步?
服务器端代码
writeTransaction = function(data, callback) {
var mysql = Meteor.require('mysql')
var connection = mysql.createConnection(info).connect()
connection.beginTransaction(Meteor.bindEnvironment(function(err) {
connection.query('DELETE FROM orders WHERE _id = ?', [data._id], Meteor.bindEnvironment( function(err) {
connection.commit( Meteor.bindEnvironment( function(err) {
}))
}))
}))
callback(null)
}
writeTransactionSync = Meteor._wrapAsync(writeTransaction)
for(var i=0; i<5; i++) {
writeTransactionSync(data[i])
}
MySQL查询日志
329 Connect root@localhost on meteor
330 Connect root@localhost on meteor
331 Connect root@localhost on meteor
332 Connect root@localhost on meteor
333 Connect root@localhost on meteor
329 Query START TRANSACTION
330 Query START TRANSACTION
331 Query START TRANSACTION
332 Query START TRANSACTION
333 Query START TRANSACTION
329 Query DELETE FROM orders WHERE _id = '34zCYZXBxEkJapkYh'
330 Query DELETE FROM orders WHERE _id = 'SNR8zTEzGCw6X7RZ2'
331 Query DELETE FROM orders WHERE _id = 'TAF2TJkN5LzFRqAnX'
332 Query DELETE FROM orders WHERE _id = '57pJbvFYmHTpM5E6a'
333 Query DELETE FROM orders WHERE _id = 'BtNLGa3gjRGAfmMFf'
331 Query COMMIT
332 Query COMMIT
329 Query COMMIT
330 Query COMMIT
333 Query COMMIT
答案 0 :(得分:4)
Meteor._wrapAsync
是同步的,前提是您在完成所有任务后触发回调。如果它知道方法已经完成,它只会阻塞光纤,所以当你调用callback(null)
时,它会假定它已经完成。
您在调用callback(null)
后使用了connection.query
,但无论您的查询是否已完成,都会调用它,并且由于查询执行MySQL需要一些时间,它可能在查询实际运行之前始终完成(并且异步)。
您应该将其放在查询的回调中:
connection.beginTransaction(function(err) {
connection.query('DELETE FROM orders WHERE _id = ?', [data._id], function(err) {
connection.commit(function(err) {
callback(null);
});
});
});
使用Meteor.bindEnvironment
时也不需要Meteor._wrapAsync
,尤其是当您在任何地方都没有使用任何Meteor代码时(在任何连接回调中都不使用流星代码,所以它不需要。)
答案 1 :(得分:1)
您可以结帐this video on Meteor._wrapAsync here in eventedmind。它在这个主题上做得很好。