繁体   English   中英

for循环内的回调

[英]Callback inside a for loop

我正在尝试遍历一系列设备并正确填充网页。 但...

for (var i=0; i<t_devices.length; i++) {
            data_final = data.replace("%Title%",t_devices[i][1] );
            data_final = data_final.replace("%IP%", t_devices[i][0]);
            console.log(i);
            getStatus(t_devices[i][0], function(status) {
                console.log(i);
                data_final = data_final.replace("%Status%","<b>"+status+"</b>");
                $('#t-container').append(data_final);
            });
        }

当然,此函数不起作用,因为for loop在其内部的回调函数之前完成,因此数据混乱。 可能我错过了一个简单的解决方案,但是我仍在为此苦苦挣扎。

最简单的解决方案是在回调周围创建一个闭合,您可以使用IIFE进行闭合:

 for (var i = 0; i < t_devices.length; i++) { data_final = data.replace("%Title%", t_devices[i][1]); data_final = data_final.replace("%IP%", t_devices[i][0]); console.log(i); (function(i, data_final) { getStatus(t_devices[i][0], function(status) { console.log(i); data_final = data_final.replace("%Status%", "<b>" + status + "</b>"); $('#t-container').append(data_final); }); }(i, data_final)); } 

如果使用ES6,只需在循环声明中用let i替换var i

否则修改您的回调函数

        for (var i=0; i<t_devices.length; i++) {
            data_final = data.replace("%Title%",t_devices[i][1] );
            data_final = data_final.replace("%IP%", t_devices[i][0]);
            console.log(i);
            getStatus(t_devices[i][0], function(index, status) {
                console.log(index);
                data_final = data_final.replace("%Status%","<b>"+status+"</b>");
                $('#t-container').append(data_final);
            }.bind(null, i));
              //first argument (null) is what would be 'this' 
              //inside function when it is called, but we don't need it
              //second (i) is what will be passed into callback as first argument
              //all other arguments will be passed as second, third and so on
        }

为什么不存储第一个循环的结果并在第一个循环结束后对其进行处理?

let deviceStatusToWork = [];
for (let i=0; i<t_devices.length; i++) {
            data_final = data.replace("%Title%",t_devices[i][1] );
            data_final = data_final.replace("%IP%", t_devices[i][0]);
            console.log(i);
            deviceStatusToWork.push(t_devices[i][0])            
        }

for (let i = 0; i < deviceStatusWork; i++) {
getStatus(deviceStatusWork[i], function(status) {                
                data_final = data_final.replace("%Status%","<b>"+status+"</b>");
                $('#t-container').append(data_final);
            });
}

我猜想,如果getStatus()返回Promise,则可以使用async/await

const myFunc = async () => {
    for (var i=0; i<t_devices.length; i++) {
        data_final = data.replace("%Title%",t_devices[i][1] );
        data_final = data_final.replace("%IP%", t_devices[i][0]);
        console.log(i);
        let status = await getStatus(t_devices[i][0]);
        console.log(i);
        data_final = data_final.replace("%Status%","<b>"+status+"</b>");
        $('#t-container').append(data_final);
    }
}

const getStatus = arg => new Promise( (resolve,reject) => {
    /*do stuff with arg*/
    resolve(status);
} );

myFunc();

由于使用的是jquery,因此可以使用each实用程序。 您的逻辑将在闭包内运行。 参见https://api.jquery.com/jquery.each/

看看这个小提琴,看看它是否有效: https : //jsfiddle.net/evm39o1s/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM