pay*_*ing 5 javascript settimeout
我有一些代码在keypress上执行,并在用户输入时将数据保存到数据库.
我添加了一个带有clearTimeout的setTimeout函数,因此用户输入的每个字符都不会发送一个Ajax请求来保存数据.
虽然setTimeout对一个输入字段很有用,但如果用户决定快速切换输入字段(在setTimeout延迟之前),则传递给callSomeAjax的参数会在执行函数之前发生变化.
正在发生的事情的简化版本......
var a = 1; //some user data
//function to call ajax script to save data to database
function callSomeAjax(a)
{
console.log(a);
}
setTimeout(function(){callSomeAjax(a)},1000); //executes callSomeAjax after 1 second delay
a=3; //change user data before callSomeAjax executes
// Result of console.log is 3, not 1 like I want it to be...
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
较新的浏览器允许您将参数传递给setTimeout,并在回调中检索它.
setTimeout(function(a){
return callSomeAjax(a);
}, 1000, a);
Run Code Online (Sandbox Code Playgroud)
或者你可以将它绑定到函数
setTimeout(function(a){
return callSomeAjax(a);
}.bind(null, a), 1000);
Run Code Online (Sandbox Code Playgroud)
除此之外,您还需要setTimeout在值的新范围内创建回调.
function callbackWithValue(a) {
return function() {
return callSomeAjax(a);
};
}
setTimeout(callbackWithValue(a), 1000);
Run Code Online (Sandbox Code Playgroud)
或者,如果你已经拥有了这个功能,并且没有别的东西可以通过,那么你可以使它更通用......
function callbackWithValue(fn) {
var args = [].slice.call(arguments, 1);
return function() {
return fn.apply(null, args);
};
}
setTimeout(callbackWithValue(callSomeAjax, a), 1000);
Run Code Online (Sandbox Code Playgroud)
最后一个显示了.bind()函数的开头.它可以进一步扩展,以允许在绑定this之后传递的附加参数的绑定和连接.
问题是,setTimeout直到1秒后才运行传入的函数.这种情况发生了什么a变化,所以当callSomeAjax(a)运行时,a它处于新值.
您需要捕获(在闭包中)a调用之前的值setTimeout.
var a = 1;
function show(a) {
console.log(a);
}
(function(a){
setTimeout(function () {
show(a)
}, 1000);
}(a));
a = 3;
Run Code Online (Sandbox Code Playgroud)
演示:http://jsfiddle.net/U59Hv/2/
| 归档时间: |
|
| 查看次数: |
1819 次 |
| 最近记录: |