【问题标题】:Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance未处理的拒绝(TypeError):无效的解构不可迭代实例的尝试
【发布时间】:2019-06-17 06:30:23
【问题描述】:

我正在尝试学习地图方法。如果我使用这种语法response.data.map(d =>,我可以迭代数据数组并查看结果,但如果我使用这种语法response.data.map(([label, CustomStep]) => {,我会收到以下错误:

Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance

你能告诉我如何解决它,以便我以后自己解决它吗?

在下面提供我的代码sn-p:

axios
.get('http://world/sports/values')
.then(response => {
    console.log("sports--->", response.data.map(d => d.customFieldValueName));
    //this.setState({ playerRanks: response.data.map(d => d.customFieldValueName) });
    // es6 map
    //Unhandled Rejection (TypeError): Invalid attempt to destructure non-iterable instance
    this.setState({
        playerRanks: response.data.map(([label, CustomStep]) => {
            label.customFieldValueName
        })
    })
})

更新 1:

嘿,我在控制台看到,data是一个数组,里面有这么多对象

 data: Array(19)
        [
            {
                "customFieldValueCode": "player1",
                "customFieldValueName": "player1",
                "isActive": "Y"
            },
            {
                "customFieldValueCode": "player 2",
                "customFieldValueName": "player 2",
                "isActive": "Y"
            }
        ]

【问题讨论】:

  • 您希望收到的数据的结构是什么?您只能使用[] 来解构数组或可迭代对象;你可以使用{} 来解构一个对象。
  • 你应该检查console.log(JSON.stringify( response.data,undefined,2))的输出错误类似于const [a,b]=22
  • @HMR 嘿,你能告诉为什么你在控制台中使用 undefined 和 2,我可以在控制台中看到这一行的值console.log(JSON.stringify( response.data,undefined,2))
  • @HMR 和我对这种console.log() 格式所做的工作通常使您正在记录的对象的完整(或者更确切地说是所需的)深度可见。使用现代浏览器 console.log(someObj) 因为它允许您在“开发工具”控制台中检查整个对象,但在服务器端环境中 console.log() 只会给你 [Object] 并使用 @将对象转换为字符串的 987654334@ 仍然只会显示该对象的“拳头”级别......
  • @cantuke 我使用 JSON.stringify 是因为即使在浏览器中,当您展开已记录的对象时,它也会显示现在的对象;不像在记录时那样(您可能已经改变了对象以适应或破坏靠近日志的代码)例如:const arr = [{name:'Ben'}];console.log(arr);arr[0].name='Jerry'; 当您展开记录的对象时,它显示名称是 Jerry 但那不是记录时的名称。 JSON.stringify(obj,undefined,2) 中的 2 是用于格式化 JSON 的制表符大小的空格数。

标签: javascript ecmascript-6 axios


【解决方案1】:

在这种情况下,您应该确定response.data 是一个数组数组,因为对于response.data.map 的每次迭代,您提供给map 的函数必须接收一个数组才能成功拉取labelCustomStep 值,这是由于您解构函数参数所使用的语法。

假设下面示例中的dataresponse.data,而parseData 函数是您传递给map 的函数:

let data = [
  [{ customFieldValueName: 'field name' }, { stepData: {} }],
  [{ customFieldValueName: 'another field name' }, { stepData: {} }]
];

let parseData = ([label, CustomStep]) => console.log(label.customFieldValueName);

parseData(data[0]); // prints out 'field name'

否则,如果 response.data 是一个对象数组,这似乎是因为您能够成功运行 response.data.map(d => d.customFieldValueName),您可以将您的地图更新为此(如果您只是想拉 @987654333 @value 出对象):

response.data.map(({ customFieldValueName }) => customFieldValueName)

【讨论】:

  • 嘿,谢谢你的回复,我在控制台看到了,数据是一个数组,里面有很多对象...更新了我的问题中的输出
【解决方案2】:

编辑:

根据提供的数据结构,您可以将代码修改为...

axios
.get('http://world/sports/values')
.then(response => {
    this.setState({
        playerRanks: response.data.map(obj => {
            return obj.customFieldValueName
        })
    })
})

    ...
    response.data.map(({customFieldValueName}) => {
        return customFieldValueName;
    })
    ...

甚至……

    ...
    response.data.map(({customFieldValueName}) => customFieldValueName)
    ...

但这将是我推荐的解决方案,为您的数据提供类型检查和适当的错误处理......

axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => {                       // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property 
    if (data && data.length) {            // making sure 'data' does exist, it is an Array and has > 0 elements
      this.setState({
        playerRanks: data.map(obj => {    // Not destructuring here in case obj isn't actually an Object
            if (obj && obj.customFieldValueName) return customFieldValueName;
            return null;
        }).filter(elem=> elem)            // BIG-O notation: This sequence is O(2N), as in iterates over the entire Array first with .map(), then iterates over the entire Array again with .filter() to clear out 'null' values
      })
    }
})

为了防止上面返回的 Array 在不符合我们的断言时包含一堆 null 元素,您可以使用 Array.reduce() 方法“过滤”掉任何 nulls.. .

axios
.get('http://world/sports/values')
.catch(err=> console.log(err))
.then(({data}) => {                       // Axios always returns an Object, so I can safely 'attempt' to destructure 'data' property 
    if (data && data.length) {            // making sure 'data' does exist, it is an Array and has > 0 elements
      this.setState({
        playerRanks: data.reduce((acc,obj) => {    // Not destructuring here in case obj isn't actually an Object
            if (!obj || !obj.customFieldValueName) return acc; // If it doesn't meet assertions just return the existing accumulator (don't add another element .ie 'null')
            return [                        
                ...acc,                      // If it conforms to the assertions the return a new accumulator, by first spreading in all existing elements and the adding the new one (customFieldValueName)
                customFieldValueName
            ]
        },[])                      // BIG-O notation: This is O(1N) or O(N), as in it will only iterate over the Array one time and the reduce() function will filter out 'null' values at the same time
      })
    }
})

注意: 我还在第一个示例的末尾添加了.filter(elem=> elem),它与新的.reduce() 功能相同,但在1N 而不是2N 操作中这样做。 p>

预先记录的数据

Array.map() method 的工作原理如下...

[1,2].map(element=> {
// element === 1, first iteration,
// element === 2, second iteration
})

Array destructuring 的工作原理如下...

[one, two, ...theRest] = [1,2,3,4,5]

// one === 1 and two === 2 and theRest = [3,4,5]

Object destructuring 的工作原理如下...

{one, three, ...theRest} = {one: 1, two: 2, three: 3, four: 4, five: 5}

// one === 1 and three === 3 and theRest === {two: 2, four: 4, five: 5}
// notice order doesn't matter here (three vs two), but you need to access valid properties from the object you're deetructuring from

因此,根据您的功能结构方式,您假设response.data 的数据结构是...

response.data === [ 
   [ 
     { customFieldValueName: 'any value' }, // label
     {}                                     // CustomStep (this could be any value, not necessarily an Object) 
   ],
   [ 
     { customFieldValueName: 'any value' }, // label
     'any value'                            // CustomStep
   ]
]

我希望这在概念上有所帮助,但如果您想要一个可行的解决方案,我们将需要...

  1. response.data 的数据结构。你能提供console.log( JSON.stringify( response.data, null, 5) )的结果吗?
  2. 您尝试分配给新 this.state.playerRanks 数组的特定值。

PS:使用当前代码查看对象解构的一个好方法是更改​​...

.then( response => {

.then( ({data}) => {

【讨论】:

  • 嘿,你能把你的cmets加回来吗,因为它有助于我们理解
  • 哇,不知道这里发生了什么,不要以为我删除了这么多。可能是版主“清理”?我确实记得我们讨论过的主题,并将在今晚晚些时候为我的回答添加一些注释和资源
猜你喜欢
  • 2021-10-10
  • 2016-12-14
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多