对象“名称”未定义,不pipe我如何select它

我不能为我的生活select正确的? 我可能会有for循环错误,所以请咨询,如果是这样的话:

function(data, callback){ data.champNames = {}; for(var c in data.champId){ val = data.champId[c]; var surl = 'https://global.api.pvp.net/api/lol/static-data/euw/v1.2/champion/'+ [val] + '?api_key=' + api_key; request(surl, function(err, response, body){ if(!err && response.statusCode == 200){ var json = JSON.parse(body); //data.champNames.push(json[val].name); console.log(json); } else { console.log('Error in Champ Name'); } }) console.log(val); } console.log(data); } 

data.champNames.push(json [val] .name)将不起作用,JSON在控制台中以如下方式返回:

 { id: 1, key: 'Annie', name: 'Annie', title: 'the Dark Child' } { id: 76, key: 'Nidalee', name: 'Nidalee', title: 'the Bestial Huntress' } { id: 15, key: 'Sivir', name: 'Sivir', title: 'the Battle Mistress' } { id: 103, key: 'Ahri', name: 'Ahri', title: 'the Nine-Tailed Fox' } 

数据是在asynchronous瀑布中使用的全局variables。

ChampId已经在一个数组中,并返回为:

  champId: [ 22, 236, 76, 21, 36, 133, 24, 103, 81, 79, 45, 15, 1, 0 ], 

data.champNames={}是你的情况下的一个字典。要使用push方法,你需要使用一个array 。 尝试这个:

 data.champNames = []; 

或者,如果你想使用字典使用这个:

 data.champNames["key"]=value; 

更新回答:

一种方法是使用立即调用的函数expression式

 for(var c in data.champId){ val = data.champId[c]; var surl = 'https://global.api.pvp.net/api/lol/static-data/euw/v1.2/champion/'+ [val] + '?api_key=' + api_key; (function(val){ request(surl, function(err, response, body){ if(!err && response.statusCode == 200){ var json = JSON.parse(body); //data.champNames.push(json[val].name); console.log(json); } else { console.log('Error in Champ Name'); } })(val); console.log(val); } 

另一个解决scheme是使用let关键字。

ES6为这个确切的情况提供了let关键字。 我们可以使用let来设置循环范围variables,而不是使用闭包。

请试试这个:

 for(let c in data.champId){ let val = data.champId[c]; var surl = 'https://global.api.pvp.net/api/lol/static-data/euw/v1.2/champion/'+ [val] + '?api_key=' + api_key; request(surl, function(err, response, body){ if(!err && response.statusCode == 200){ var json = JSON.parse(body); //data.champNames.push(json[val].name); console.log(json); } else { console.log('Error in Champ Name'); } }) } 

在访问对象似乎是一个问题时,更大的问题实际上是如何处理数据。 您正在同步循环( for...in )内执行asynchronous操作( request(...) )。 由于JavaScript的工作方式,这意味着循环将在执行任何requestcallback之前完成。

代码中的问题已经在其他问题和资源中得到了广泛的讨论,所以我强烈build议您在做任何事情之前阅读以下内容:

  • 并发模型和事件循环
  • 循环中的JavaScript闭包 – 一个简单实用的例子
  • 为什么我的variables在函数内部修改后没有改变? – asynchronous代码引用
  • 如何返回来自asynchronous调用的响应?

为了解决你的问题,你应该看看承诺 。 我们将为data.champId数组中的每个条目创build一个新的承诺。 承诺基本上是未来价值的占位符。 一个承诺可以解决一个价值,或者如果有错误被拒绝 。 在这里,每个承诺将是通过request接收到的响应的占位符,这是一个asynchronous过程。 具体而言,这些承诺中的每一个都将parsing为响应对象的name 。 像Promise.all这样的Helper方法允许我们在解决了多个 promise后执行一个动作。

 function fetchNames(data) { // Promise.all returns a new promise that resolves when all promises passed to it // are resolved return Promise.all(data.champId.map(function(id) { var surl = 'https://global.api.pvp.net/api/lol/static-data/euw/v1.2/champion/'+ id + '?api_key=' + api_key; // Create a new promise for each entry in data.champId return new Promise(function(resolve, reject) { request(surl, function(err, response, body){ if (!err && response.statusCode == 200){ var result = JSON.parse(body); resolve(result.name); // the response is an object with a property name } else { reject('Unable to load entry "' + id + '"'); } }); }); } fetchNames({champId: [ 22, 236, 76, 21, 36, 133, 24, 103, 81, 79, 45, 15, 1, 0 ]}) .then(function(names) { console.log(names); }) .catch(function(error) { // An error occured }); 

你正试图在一个对象中进行推送:你声明data.champNames = {} ,但是对于一个推式,你需要一个数组data.champNames = []; )。

阅读代码,我可以假设你正在尝试读取JSON数组的val-th元素,而不是id == val的JSON元素。 如果你想获得id == val的元素的名字,你必须在JSON对象内进行search。