未处理的拒绝(TypeError):破坏非迭代实例的无效尝试

时间:2019-01-23 15:57:41

标签: javascript ecmascript-6 axios

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

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

您能告诉我如何修复它,以便将来自己修复吗?

在下面提供我的代码段:

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: Array(19)
        [
            {
                "customFieldValueCode": "player1",
                "customFieldValueName": "player1",
                "isActive": "Y"
            },
            {
                "customFieldValueCode": "player 2",
                "customFieldValueName": "player 2",
                "isActive": "Y"
            }
        ]

2 个答案:

答案 0 :(得分:2)

编辑:

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

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

OR

    ...
    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()方法来“过滤”出任何{{ 1}} s ...

null

注意: 我还在第一个示例的末尾添加了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操作。

PRE记录的数据

2N method的工作方式...

Array.map()

Array destructuring的工作方式...

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

Object destructuring的工作方式...

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

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

因此,根据函数的结构方式,您假设{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

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

  1. response.data === [ [ { customFieldValueName: 'any value' }, // label {} // CustomStep (this could be any value, not necessarily an Object) ], [ { customFieldValueName: 'any value' }, // label 'any value' // CustomStep ] ] 的数据结构。您能否提供response.data
  2. 的结果
  3. 您要分配给新console.log( JSON.stringify( response.data, null, 5) )数组的特定值。

PS:查看当前代码对对象进行销毁的一种好方法是更改​​...

this.state.playerRanks

收件人

.then( response => {

答案 1 :(得分:0)

在这种情况下,您应该确定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)而引起的,则可以将地图更新为此(如果您只是想将customFieldValueName值从对象中拉出):

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