我是nodeJs的新手。在for循环中,我从一些url获取数据后得到array [i]值undefined。我不知道如何解决这个问题。请帮我。
这是我的代码
urls =['url1','url2','url3','url4']
for (var i = 0; i < urls.length; i++) {
console.log(urls[i]) // getting value
var opt = {
url :urls[i],
headers: {
'Authorization': 'Bearer '+reply
}
}
request.get(opt,function(error,response,body) {
console.log(urls[i]) // getting undefined
if(!error) {
enrichment_data.push({type:body});
} else {
enrichment_data.push({type:''})
}
})
}
答案 0 :(得分:4)
根据MDN,理解JavaScript闭包的这种逻辑错误是a common mistake。
有两种实用的方法可以解决这个问题。仅使用ES5,解决此问题的最常规方法是使用urls.forEach()
代替:
var urls = ['url1', 'url2', 'url3', 'url4']
urls.forEach(function(url, i) {
console.log(urls[i]) // getting value
var opt = {
url: urls[i],
headers: {
'Authorization': 'Bearer ' + reply
}
}
request.get(opt, function(error, response, body) {
console.log(urls[i]) // getting undefined
if (!error) {
enrichment_data.push({
type: body
});
} else {
enrichment_data.push({
type: ''
})
}
})
})
使用此方法,您可以创建一个新的函数作用域,即使在异步函数中也可以保留每个i
的值,这样变量引用就不会被{{的后续迭代所覆盖。 1}}你之前的循环。
您的第二个选择是使用let
引入ES6词法范围变量声明,如下所示:
for
词法范围意味着在for循环的块范围内对var urls = ['url1', 'url2', 'url3', 'url4']
for (let i = 0; i < urls.length; i++) {
console.log(urls[i]) // getting value
var opt = {
url: urls[i],
headers: {
'Authorization': 'Bearer ' + reply
}
}
request.get(opt, function(error, response, body) {
console.log(urls[i]) // getting undefined
if (!error) {
enrichment_data.push({
type: body
});
} else {
enrichment_data.push({
type: ''
})
}
})
})
的任何引用,即使在异步函数的主体内,也会引用特定的迭代i
循环的em>,允许它按照它应该的样子运行。
答案 1 :(得分:0)
Patrick的精彩回答。我想补充几点。
要回答这个问题,为什么您在undefined
获得console.log(urls[i])
,因为i
的值为4且索引为4
时没有任何内容。
现在为什么我是4. request
是一个异步调用,一旦你调用request.get
,它就会经历事件循环并被写入堆栈(使用正确的URL)调用。 。只有在当前调用结束时才会调用此堆栈,即在for
循环结束后。只有在i为4且var
为全局范围
以下是了解事件循环如何工作的great video。