为什么我得到 for 循环的 array[i] 值未定义

siv*_*iva 0 node.js express

我是 nodeJs 的新手。在 for 循环中,从某个 url 获取数据后,我得到了未定义的 array[i] 值。我不知道如何解决这个问题。请帮我。

这是我的代码

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:''})
   }
 })
}
Run Code Online (Sandbox Code Playgroud)

Pat*_*rts 5

根据 MDN,这种理解 JavaScript 闭包的逻辑错误是一个常见的错误

有两种实用的方法可以解决这个问题。仅坚持使用 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: ''
      })
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

使用此方法,您可以创建一个新的函数作用域i,即使在异步函数中,该作用域也会保留 each 的值,以便变量引用不会被for您之前使用的循环的后续迭代覆盖。

您的第二个选择是使用let如下方式引入 ES6 词法范围变量声明:

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: ''
      })
    }
  })
})
Run Code Online (Sandbox Code Playgroud)

词法作用域意味着i在 for 循环的块作用域内的任何引用,即使在异步函数的主体内,也将引用循环特定迭代for,使其表现得像它应该的那样。