无法在函数内传递全局变量

时间:2017-07-08 17:46:15

标签: javascript node.js rest loops variables

我尝试使用需要在另一个函数中重新运行的变量来运行FOR循环,我需要在第一个函数中编写代码, 但是函数接收它们为" undefined"。

当除了ledTypes2之外,collectionChecking函数中的变量是局部的,当handleResponse2的函数试图调用他时,hostIndx2的变量是未定义的。此函数应将响应呈现为HTML页面内ledTypes2方法的图标。

var fetch = require('node-fetch');

var ledTypes = {
    green: "<img id='logo' src='green.png' height='30' width='30'>",
    red: "<img id='logo' src='red.png' height='30' width='30'>",
    yellow: "<img id='logo' src='yellow.png' height='30' width='30'>"
};

var hosts2 = ['http://host1.com','host2.com','host3.com','host4.com'];
var hostIndx2 = 0;

var lengthVal = hosts2.length;
var token = '1213232431';
    function collectionChecking() {

        console.log("im inside the func" + hostIndx2 + "---" + lengthVal);
        for (; hostIndx2 < lengthVal; hostIndx2++) {
            console.log(hostIndx2);
            let url = hosts2[hostIndx2];
            // sendReq();
            fetch(url , {method: 'GET', headers:{"X-AUTH-TOKEN": token, "Content-Type": "text/plain"}, timeout: 30000}
            ).then(function (res, hostIndx2) {
                    console.log(res.status, hostIndx2);
                    handleLedResponse2(res, hostIndx2);

                });
        }
    }

function handleLedResponse2(res, hostIndx2) {
    var curSpan = document.getElementById('col_host_' + hostIndx2);
    console.log("IM HERE" + res.status + "---" + hostIndx2);
    if (res.status === 200 || res.status === 204) {
        curSpan.innerHTML = ledTypes.green;
    } else if (res.status === 500 || res.status === 404) {
        curSpan.innerHTML = ledTypes.red;
    } else if (res.status === 300 || res.status === 301 || res.status === 302) {
        curSpan.innerHTML = ledTypes.yellow;
    }
}

1 个答案:

答案 0 :(得分:0)

此代码中存在多个错误。

对于初学者,您不能在异步响应中使用for循环索引变量。 for循环将在handleLedResponse2()被调用之前完全完成,因此它将没有所需的值。

其次,你声明一个.then()处理程序在这一行上有两个参数:

.then(function (res, hostIndx2) {

通过规范,.then()处理程序只传递一个参数。因此,您将定义一个名为hostIndx2的参数,该参数始终为undefined,并且它将“隐藏”同名的更高范围的变量,因此您无法访问它。
 这就是为什么您看到值始终为undefined。要解决的第一件事就是将上面的代码更改为:

.then(function (res) {

这将使您可以访问更高范围的hostIndx2变量(它将不再是undefine)。但是,由于for循环和异步fetch()调用的混合,它可能不具有所需的值,因为for循环将在任何{{1}之前运行完成处理程序被调用。

我认为这解释了这部分代码有什么问题,但我不能完全推荐完整的修复,因为我不确定你要做什么。我认为fetch().then()根本不应该是一个更高范围的变量,因为这只会导致问题,并为其他事情提供机会来破坏它。它应该是一个局部变量,然后你应该将它作为参数传递给你想要访问它的任何东西。

要解决异步访问它的问题,有多个选项。您可以切换到使用hostIndx2for循环中定义它,并且循环的每次调用都将获得其自己的变量版本(解决异步访问问题)。或者,您可以将循环更改为使用let,这将为循环的每次调用创建一个新的唯一范围。

对你要做的事情进行一些猜测,这是一个清理版本:

forEach

P.S。我在这里有点困惑,因为你的问题被标记为node.js,看起来你正在使用node-fetch(暗示一个node.js环境),但是你显示const fetch = require('node-fetch'); const ledTypes = { green: "<img id='logo' src='green.png' height='30' width='30'>", red: "<img id='logo' src='red.png' height='30' width='30'>", yellow: "<img id='logo' src='yellow.png' height='30' width='30'>" }; const hosts2 = ['http://host1.com','http://host2.com','http://host3.com','http://host4.com']; const token = '1213232431'; function collectionChecking() { hosts2.forEach(function(url, index) { console.log("im inside the func" + index); fetch(url , {method: 'GET', headers:{"X-AUTH-TOKEN": token, "Content-Type": "text/plain"}, timeout: 30000}).then(function (res) { console.log(res.status, index); handleLedResponse2(res, index); }); } } function handleLedResponse2(res, hostIndx2) { let curSpan = document.getElementById('col_host_' + hostIndx2); console.log("IM HERE" + res.status + "---" + hostIndx2); if (res.status === 200 || res.status === 204) { curSpan.innerHTML = ledTypes.green; } else if (res.status === 500 || res.status === 404) { curSpan.innerHTML = ledTypes.red; } else if (res.status === 300 || res.status === 301 || res.status === 302) { curSpan.innerHTML = ledTypes.yellow; } } 这不是你的东西可以在node.js中使用 - 通常是在浏览器中运行的代码。