对象“名称”未定义,无论我如何选择它

时间:2016-12-12 14:57:00

标签: javascript arrays node.js

我不能为我的生活选择这个吗?我可能有错误的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' }

数据是异步瀑布中使用的全局变量。

ChampId已经在一个数组中,并以:

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

3 个答案:

答案 0 :(得分:1)

data.champNames={}是您的字典中的字典。要使用push方法,您需要使用array。试试这个:

data.champNames = [];

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

data.champNames["key"]=value;

更新回答:

一种方法是使用Immediately-Invoked Function 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);                
 } 

另一种解决方案是使用let关键字。

  

ES6为这种情况提供了let关键字。代替   使用闭包,我们可以使用let来设置循环范围变量。

请试试这个:

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');
            }
        })               
    }

答案 1 :(得分:1)

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

您的代码中的问题已在其他问题和资源中得到广泛讨论,因此我强烈建议您在执行任何其他操作之前阅读以下内容:

为了解决您的特定问题,您应该查看Promises。我们将为data.champId数组中的每个条目创建一个新的承诺。承诺基本上是 future 值的占位符。如果出现错误,承诺可以解析到某个值,或者拒绝。在这里,每个promise都是通过request收到的响应的占位符,这是一个异步过程。特别是,这些承诺中的每一个都将解析为响应对象的name。辅助方法(例如Promise.all)允许我们在多个承诺得到解决后执行操作。

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
  });

答案 2 :(得分:0)

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

读取代码我可以假设您正在尝试读取JSON数组的第val个元素,而不是ID == val的JSON元素。如果要获取id == val元素的名称,则必须在JSON对象内进行搜索。