对象"name"未定义,无论我如何选择它



我一生不能正确选择吗?我可能有错误的循环,所以如果是这样,请建议:

    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 ],

data.champNames={}是您的情况下的字典。要使用push方法,您需要使用array。尝试以下操作:

data.champNames = [];

或,如果您想使用字典,请使用以下方式:

data.champNames["key"]=value;

更新答案:

一种方法是使用立即启动的函数表达式

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关键字。代替 使用闭合,我们只能使用让设置循环范围变量。

请尝试:

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)内的异步操作(request(...))。由于JavaScript的工作方式,这意味着循环将在执行任何request回调之前先完成。

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

  • 并发模型和事件循环
  • javaScript闭合循环 - 简单实践示例
  • 为什么在函数内部修改它之后,为什么我的变量不变? - 异步代码参考
  • 如何从异步呼叫中返回响应?

为了解决您的特定问题,您应该研究 Promises 。我们将为data.champId数组中的每个条目创建一个新的承诺。承诺基本上是A 未来价值的占位符。如果有错误,承诺可以可以解决被拒绝。在这里,每个诺言都是通过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
  });

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

阅读代码,我可以假设您正在尝试读取JSON数组的VAL-TAL元素,而不是具有ID == Val的JSON元素。如果您想获得具有ID == Val的元素的名称,则必须在JSON对象内进行搜索。

最新更新