回调的闭包问题

Closure issue with callback

本文关键字:问题 闭包 回调      更新时间:2023-09-26

我有一个回调关闭问题。

每次调用这个函数,我得到tmp = 1。我在回调中设置它。

为什么会发生?我该如何解决它呢?

var tmp = 1;
var getConnection = function() {
    console.log(tmp);
    MongoClient.connect(url, function(err, db) {
        tmp = 2;
    });
};
var tmp = 1; // set tmp to 1
var getConnection = function() {
    console.log(tmp); // log current value of tmp
    MongoClient.connect(url, function(err, db) {
        tmp = 2; // set tmp to 2
    });
};

我没有看到getConnection()被调用,但让我们假设您在声明后立即调用它。

getConnection()中发生的是你1)记录tmp的电流值,然后2)尝试连接到Mongo,然后3)将tmp的值设置为2。

为了回答你的问题,我认为缺少一些数据。

我猜你在某种循环中调用getConnection()函数,例如

for (var i = 0; i < l; ++i) {
    getConnection(i);
}

在这种情况下,串行代码(即循环和console.log(tmp))将在所有回调之前执行,在您的情况下:

function(err, db) {
    tmp = 2; // set tmp to 2
}

'1'将始终显示,因为只有在写入控制台后,该值才会更新为'2'。

MongoClient.connect是一个异步操作,所以,如果你想使用tmp的更新值,你应该这样做:

var tmp = 1; // set tmp to 1
var getConnection = function(callback) {
   var ctx = this; //or whatewever you want the context to be
   console.log(tmp); // log current value of tmp
   MongoClient.connect(url, function(err, db) {
     tmp = 2; // set tmp to 2
     callback.call(ctx, tmp); //you have to choose the context
  });
};
getConnection(function(tmp){
   //do some magic with tmp
})

顺便说一下,将tmp作为全局变量并不是一个好主意,它可能会被其他变量污染,并可能导致许多问题