You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何循环中$.get()的回调仅执行最后一次?技术求助

问题:循环中仅最后一个设备的AJAX回调执行

我在程序中编写了如下代码,本意是遍历所有设备,通过$.get()请求设备缩略图,根据请求成功或失败执行对应操作。但从控制台日志发现,循环中每个设备都打印了before get日志,却仅最后一个设备的done/always回调日志被输出。

控制台日志

before get: efbekmtfgjyz9pr_0_0
before get: gu2u1hnspgo2vhk_1_0
done get: gu2u1hnspgo2vhk_1_0
always get: gu2u1hnspgo2vhk_1_0 

代码片段

var deviceIx = 0;
while (deviceIx < service.devices.length) {

var devId = buildUniqueHTMLId(
    device.jid + "_" + deviceIx + "_" + serviceIx
);
console.log("before get: " + devId);
$.get(device.thumbnail).done(function () {
    console.log("done get: " + devId);
    $('.devicelist #deviceImg-' + devId).attr("src", device.thumbnail);

    var img = device.thumbnail;
    var caption = "FRONT";
    $("#deviceImagesCarousel .carousel-inner").append("<div class='carousel-item'><img class='d-block w-100' src='" + img + "' alt='" + img + "'><div class='carousel-caption'>" + caption +"</div></div>");
    $("#deviceImagesCarousel .carousel-indicators").append("<li data-target='#deviceImagesCarousel' data-slide-to='0' ></li>");
    $('#deviceImagesCarousel .carousel-inner .carousel-item').first().addClass('active');
    $('#deviceImagesCarousel .carousel-indicators li').first().addClass('active');
}).fail(function () {
    console.log("fail get: " + devId);
    $('.devicelist #deviceImg-' + devId).attr("src", 'script/iopsys/devicemanager/images/hardwareversions/gateway/na_t.png');
    $("#deviceImagesCarousel .carousel-inner").append("<div class='carousel-item'><img class='d-block w-100' src='script/iopsys/devicemanager/images/hardwareversions/gateway/na_t.png' alt='First slide'></div>");
    $("#deviceImagesCarousel .carousel-indicators").append("<li data-target='#deviceImagesCarousel' data-slide-to='0' ></li>");
    $('#deviceImagesCarousel .carousel-inner .carousel-item').first().addClass('active');
    $('#deviceImagesCarousel .carousel-indicators li').first().addClass('active');
}).always(function() {
    console.log("always get: " + devId);
    $('.devicelist #deviceImg-' + devId).attr("src", device.thumbnail);
});

原因分析

这是JavaScript闭包的经典问题:

  1. $.get()是异步请求,回调函数(done/fail/always)会在请求完成后才执行,但while循环是同步执行的,会快速遍历完所有设备。
  2. 循环里的devId和device变量属于函数作用域(while没有块级作用域),当回调函数最终触发时,循环已经结束,这两个变量的值已经被覆盖为最后一次循环的设备数据。
  3. 所以所有回调函数都会引用最后一个设备的变量值,自然只会打印最后一个设备的日志,操作也只会针对最后一个设备生效。

内容的提问来源于stack exchange,提问作者Amber Akkermans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 22:39:18