javascript - 未处理的拒绝 (TypeError) : Invalid attempt to destructure non-iterable instance

标签 javascript ecmascript-6 axios

我正在尝试学习 map 方法。如果我使用此语法 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:

咦,我在console里看到,data是一个数组,里面有很多对象

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

最佳答案

编辑:

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

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 操作中执行此操作。

预先记录的数据

下面是 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. 的结果吗
  3. 您尝试分配给新的 this.state.playerRanks 数组的特定值。

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

.then( 响应 => {

.then( ({data}) => {

关于javascript - 未处理的拒绝 (TypeError) : Invalid attempt to destructure non-iterable instance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54331101/

相关文章:

javascript - 在 ES6 中从父类调用子方法

javascript - Node js,函数不等待响应

javascript - 使用删除按钮而不是 Html.ActionLink 来调用 Controller 的操作?

javascript - 如何在不使用 Webpack 的情况下从公共(public)文件夹获取图像

javascript - 调用 clearRect 后,HTML5 Canvas 不会在 Chrome 中重绘

promise - Axios 使用拦截器处理错误(js promise )

javascript - HTTPInterceptor 没有拦截来自 Angular 中第 3 方小部件的 http 请求

javascript - 使用 CSS 标记元素以便稍后使用 JS 检测它们

javascript - Babelify 多个目录中的文件

javascript - Angular 和 RxJs 结合了两个 http 请求