Meteor._wrapAsync

时间:2014-02-08 10:10:33

标签: javascript mysql node.js meteor

我用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

2 个答案:

答案 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。它在这个主题上做得很好。