我是JavaScript的初学者。我开发了一个代码来获取一些url输出使用获取API。当我使用下面的代码时,它说,在循环中声明的函数引用了一个外部作用域变量。我知道这是由于obj变量的外部范围,但我怎么能使它工作。请帮助。下面是代码
var obj = [
{"Id":"10101","descr":"server1.com"},
{"Id":"10102","descr":"server2.com"},
{"Id":"10103","descr":"server3.com"},
{"Id":"10104","descr":"server4.com"},
{"Id":"10105","descr":"server5.com"},
{"Id":"10106","descr":"server6.com"},
{"Id":"10107","descr":"server7.com"}
];
var temp = [];
for (var i = 0; i < obj.length; i++){
var id = obj[i].Id;
fetch('https://abced.com/api/'+id+'/value', {
method : "GET",
headers: { "Authorization": "xyz" }
})
.then(res => res.json())
.then(data => {
var stats = data.status;
if (stats != "OK") {
temp.push({ Id: obj[i].Id, descr: obj[i].descr, value:"ERROR" });
}
console.log(temp);
})
.catch(x => console.log("fail:", x))
}
我的期望输出是。(Id和描述符的值取决于代码中的if语句)
[{"Id": "10101","descr": "server1.com","status": "ERROR"},
{"Id": "10103","descr": "server3.com","status": "ERROR"},
{"Id": "10104","descr": "server4.com","status": "ERROR"}]
我建议使用async...await
语法,这比许多.then()处理程序更容易阅读。
我们将使用for .. of
循环来遍历obj数组中的每个Id,描述值,并为每个Id,描述值调用相应的fetch()
。
我们等待每个fetch调用的结果,然后测试状态。如果不正确,则添加到结果数组。
var obj = [
{"Id":"10101","descr":"server1.com"},
{"Id":"10102","descr":"server2.com"},
{"Id":"10103","descr":"server3.com"},
{"Id":"10104","descr":"server4.com"},
{"Id":"10105","descr":"server5.com"},
{"Id":"10106","descr":"server6.com"},
{"Id":"10107","descr":"server7.com"}
];
async function getResults() {
const results = [];
for(let { Id, descr} of obj) {
const data = await fetch('https://abced.com/api/' + Id + '/value', {
method : "GET",
headers: { "Authorization": "xyz" }
}).then(res => res.json());
if (data.status !== 'OK') {
results.push({ Id, descr, value: 'ERROR' })
}
}
return results;
}
async function test() {
const results = await getResults();
console.log('Results:', results)
}
test();
下面是我模拟出fetch的代码片段,这应该会让你知道会发生什么。
fetchMock返回id为10101、10103、10104的状态为'BAD',其他所有id为'OK'。
// For testing only, replace with fetch when appropriate...
function fetchMock(url) {
let id = url.split('/')[4];
if ([10101, 10103, 10104].includes(+id)) {
return Promise.resolve({ json() { return Promise.resolve({ status: 'BAD'})}})
} else {
return Promise.resolve({ json() { return Promise.resolve({ status: 'OK'})}})
}
}
var obj = [
{"Id":"10101","descr":"server1.com"},
{"Id":"10102","descr":"server2.com"},
{"Id":"10103","descr":"server3.com"},
{"Id":"10104","descr":"server4.com"},
{"Id":"10105","descr":"server5.com"},
{"Id":"10106","descr":"server6.com"},
{"Id":"10107","descr":"server7.com"}
];
async function getResults() {
const results = [];
for(let { Id, descr} of obj) {
const data = await fetchMock('https://abced.com/api/' + Id + '/value', {
method : "GET",
headers: { "Authorization": "xyz" }
}).then(res => res.json());
if (data.status !== 'OK') {
results.push({ Id, descr, value: 'ERROR' })
}
}
return results;
}
async function test() {
const results = await getResults();
console.log('Results:', results)
}
test()
.as-console-wrapper { max-height: 100% !important; }