Javascript 函数内部的闭包不是 "remember" 它的环境
Javascript closure inside function doesn't "remember" it's environment
我有一个函数,它从数据库中检索数据并将其传递给回调。出于优化目的,我希望此数据最多每 60 秒更新一次。我的闭包函数如下所示:
function delayedUpdate(fn, delay, callback) {
var nextCall = Date.now();
var data = false;
(function () {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
})();
}
我注意到当我 "construct" 这个经常被调用的函数在我想要的函数中时,我基本上是在循环中创建一个闭包,所以它没有机会正常工作:
function update()
{
delayedUpdate(server.getDbData, 60000, function (err, data) {
someDataToRender = data;
});
}
在其他函数中包装 delayedUpdate
并分配给变量也不起作用。我怎样才能实现我的目标?我知道这可能是个愚蠢的问题,但我仍在学习。
你的代码没问题。您只需要在函数外声明变量 nextCall
和 data
:
var nextCall = Date.now();
var data = false;
function delayedUpdate(fn, delay, callback) {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
}
我想你想要的是你的原始代码:
function delayedUpdate(fn, delay, callback) {
var nextCall = Date.now();
var data = false;
return function () {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
};
}
那么您的 update
函数将是:
var update = delayedUpdate((server.getDbData, 60000, function (err, data) {
someDataToRender = data;
});
即update
是调用delayedUpdate
返回的函数。当您调用 update
时,它会进行时间戳检查。
需要注意的一件事:getDbData
函数可能不喜欢在没有 server
对象的上下文的情况下被调用,无论它是什么。如果是这样,则设置应如下所示:
var update = delayedUpdate((server.getDbData.bind(server), 60000, function (err, data) {
someDataToRender = data;
});
我有一个函数,它从数据库中检索数据并将其传递给回调。出于优化目的,我希望此数据最多每 60 秒更新一次。我的闭包函数如下所示:
function delayedUpdate(fn, delay, callback) {
var nextCall = Date.now();
var data = false;
(function () {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
})();
}
我注意到当我 "construct" 这个经常被调用的函数在我想要的函数中时,我基本上是在循环中创建一个闭包,所以它没有机会正常工作:
function update()
{
delayedUpdate(server.getDbData, 60000, function (err, data) {
someDataToRender = data;
});
}
在其他函数中包装 delayedUpdate
并分配给变量也不起作用。我怎样才能实现我的目标?我知道这可能是个愚蠢的问题,但我仍在学习。
你的代码没问题。您只需要在函数外声明变量 nextCall
和 data
:
var nextCall = Date.now();
var data = false;
function delayedUpdate(fn, delay, callback) {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
}
我想你想要的是你的原始代码:
function delayedUpdate(fn, delay, callback) {
var nextCall = Date.now();
var data = false;
return function () {
if (nextCall <= Date.now()) {
nextCall = Date.now() + delay;
fn(function (err, res) {
data = err ? false : res;
callback(err, data);
});
} else {
callback(null, data);
}
};
}
那么您的 update
函数将是:
var update = delayedUpdate((server.getDbData, 60000, function (err, data) {
someDataToRender = data;
});
即update
是调用delayedUpdate
返回的函数。当您调用 update
时,它会进行时间戳检查。
需要注意的一件事:getDbData
函数可能不喜欢在没有 server
对象的上下文的情况下被调用,无论它是什么。如果是这样,则设置应如下所示:
var update = delayedUpdate((server.getDbData.bind(server), 60000, function (err, data) {
someDataToRender = data;
});