我尝试使用需要在另一个函数中重新运行的变量来运行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;
}
}
答案 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()
根本不应该是一个更高范围的变量,因为这只会导致问题,并为其他事情提供机会来破坏它。它应该是一个局部变量,然后你应该将它作为参数传递给你想要访问它的任何东西。
要解决异步访问它的问题,有多个选项。您可以切换到使用hostIndx2
在for
循环中定义它,并且循环的每次调用都将获得其自己的变量版本(解决异步访问问题)。或者,您可以将循环更改为使用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中使用 - 通常是在浏览器中运行的代码。