In JavaScript 能保证是单线程的吗?很明显,无论JavaScript是单线程的,仍然需要注意。
我想知道以下伪代码是否总是可预测的(我正在"使用"jQuery)
var lastReq;
$('#button').click(function()
{
if (lastReq) lastReq.abort();
lastReq = $.ajax(...);
});
情况可能是在单击事件和中止之间,来自服务器的数据通过并将事件放在 de eventqueue 上。如果这种情况发生在中止之前,将触发 ajax 帖子的成功事件。我不知道如何真正测试这种可能的竞争条件。
有谁知道这是如何工作的?或者如何用准备好的示例来测试这一点?
这种解决方法是否真的有用并且是防弹的(我试图发挥创造力),但是,由于 jQuery 1.5 ajax 方法返回一个延迟对象,lastReq
state()
可用的方法
从 http://api.jquery.com/deferred.state/
deferred.state() 方法返回一个字符串,表示 Deferred 对象的当前状态。延迟对象可以处于以下三种状态之一:
。
"solved":延迟对象处于已解决状态,这意味着已为对象调用了deferred.resolve()或deferred.resolveWith(),并且已调用(或正在调用)doneCallbacks。
所以你可以像这样重构你的代码
var lastReq;
$('#button').click(function() {
if (lastReq) {
if (lastReq.state() === "resolved") {
return false; /* done() of the previous ajax call is in the process of
being called. Do nothing and wait until the state
is resolved */
}
else {
lastReq.abort();
}
}
lastReq = $.ajax(url).done(function() {
/* do something */
lastReq = null;
});
});
希望这可以帮助您找到一个工作的想法,但我怀疑实际上并不需要这种解决方法
编辑:一旦您中止请求,浏览器就不应该再侦听它了。因此,当它到达事件队列中的响应时,我的猜测是它应该将其丢弃。
但是,如果您遇到问题,可以尝试以下操作:
如果检测到它不再需要运行,您能否检查您的成功函数 + url 以自行取消?
例如(我并不是说你应该这样做,我还没有尝试将任何东西附加到 jqXHR 请求):
var numReq = 0, lastReq;
$('#button').on('click', function(e) {
if (lastReq) { lastReq.abort(); }
numReq ++;
lastReq = $.ajax({
success : function(d, s, x) {
if (x.reqNum < numReq) { return; }
}
});
lastReq.reqNum = numReq;
});
我的理解是,在按钮单击完成之前,ajax 事件不会添加到事件队列中,因此您(理论上)不必担心在 ajax 之后设置 reqNum...
我还尝试了以下代码:
var numReq = 0, lastReq, timer = 100,
c = setInterval(function() {
if (lastReq) { lastReq.abort(); }
numReq ++;
lastReq = $.ajax({
url : 'index.html',
cache : false,
success : function(d, s, x) {
if (x.reqNum < numReq) { console.log('it happens'); }
}
});
lastReq.reqNum = numReq;
}, timer);
改变计时器以尝试匹配(尽可能接近)页面的加载时间。我没有出现"它发生"。