2017-04-20 27 views
0

给出以下节点\ JavaScript代码,由于某些原因,计数器变量(failedCounter, successMatchedCounter, successUnmatchedCounter)在运行时以意外方式计算。我认为这是一个范围问题,是异步的问题,但仍然无法找到原因。数字变量递增 - 运行时发生意外的数字

更新:我认为,当以connection.query()所有呼叫完成我应该得到通知,然后才记录的计数器..

"//BUG: counted numbers are not logged as expected"行:

var MongoClient = require('mongodb').MongoClient; 
var mysql = require('mysql2'); 
var fs = require('fs'); 

var dir = './logs'; 
if (!fs.existsSync(dir)) { 
    fs.mkdirSync(dir); 
} 

var testMode = false; 

var mongoUrl = 'mongodb://xxx:27017/yy'; 
var mySqlconnString = { 
    host: 'xxxxx', 
    user: 'xxxx', 
    password: 'xxxxx', 
    database: 'xxxxx' 
}; 

var connection = mysql.createConnection(mySqlconnString); 

connection.connect(function(err) { 
    if (err) { 
     console.log('Error connecting to MySql DB'); 
     return; 
    } 

    console.log('Connection established to MySql DB'); 

    MongoClient.connect(mongoUrl, function(err, db) { 

     if (err) { 
      console.log('Error connecting to MongoDB'); 
      return; 
     } 

     console.log("Connection established to MongoDB"); 

     markSitesAsDeleted(db, function() { 
      console.log('closing DBs connections..'); 
      connection.end(function(err) {}); 
      db.close(); 
     }); 
    }); 
}); 


var failedCounter = 0; 
var successMatchedCounter = 0; 
var successUnmatchedCounter = 0; 
var totalCounter = 0; 

var markSitesAsDeleted = function(db, closeConnectionsCallback) { 
    console.log(`\nMigration process is starting..`); 
    var cursor = db.collection('someCollection').find({ 
     "isDeleted": true 
    }); 

    console.log(`Migrating data..\r\n`); 

    cursor.each(function(err, siteDoc) { 
     if (siteDoc != null) { 
      var siteID = Math.trunc(siteDoc._id) 

      if (testMode === false) { 
       connection.query(`CALL MarkSiteAsDeleted_3(${siteID})`, function(error, rows) { 
        if (error) { 
         //TODO: Print error 
         failedCounter++; 
         fs.appendFileSync('logs/log.txt', `Error occured when calling MarkSiteAsDeleted_3 SP for SiteId=${siteID}. see error: ${JSON.stringify(error)}\n`); 
        } else { 
         if (rows.affectedRows === 1) { // Has match 
          successMatchedCounter++; 
         } else { 
          successUnmatchedCounter++; 
         } 
        } 
       }); 
      } 

      totalCounter++; 

     } else { 
      //BUG: counted numbers are not logged as expected 
      fs.appendFileSync('logs/log.txt', `Total: ${totalCounter}, Success and Matched: ${successMatchedCounter}, Success but Unmatched: ${successUnmatchedCounter}, Failed: ${failedCounter}\r\n`); 
      closeConnectionsCallback(); 
     } 
    }); 
}; 

回答

0

它肯定看起来像一个异步问题。在cursor.each内部,您可以使用异步回调来处理connection.query。所以当each迭代时,它会进行查询。但所有查询都是异步运行的。

一旦每个完成设置所有的异步查询,然后命中您的else它使用同步写入。这是问题发生的地方。发生写操作时,某些异步查询处理程序尚未完成。

+0

如何在所有异步查询完成后收到通知? –

+0

没有人回答“在完成所有查询后我如何得到通知?”。有完整的图书馆,网站,论坛和专门讨论这个确切问题的帖子。这是一个设计问题,我不熟悉你的设计以及你在编写代码时如何处理异步任何事情。 – gforce301