我有一些代码在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...
关于小提琴的代码
有任何想法吗?
问题是,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;
演示:http://jsfiddle.net/U59Hv/2/
较新的浏览器允许您将参数传递给setTimeout
,并在回调中检索它.
setTimeout(function(a){ return callSomeAjax(a); }, 1000, a);
或者你可以将它绑定到函数
setTimeout(function(a){ return callSomeAjax(a); }.bind(null, a), 1000);
除此之外,您还需要setTimeout
在值的新范围内创建回调.
function callbackWithValue(a) { return function() { return callSomeAjax(a); }; } setTimeout(callbackWithValue(a), 1000);
或者,如果你已经拥有了这个功能,并且没有别的东西可以通过,那么你可以使它更通用......
function callbackWithValue(fn) { var args = [].slice.call(arguments, 1); return function() { return fn.apply(null, args); }; } setTimeout(callbackWithValue(callSomeAjax, a), 1000);
最后一个显示了.bind()
函数的开头.它可以进一步扩展,以允许在绑定this
之后传递的附加参数的绑定和连接.