从 api 推送数组数据会导致无限循环

Posted

技术标签:

【中文标题】从 api 推送数组数据会导致无限循环【英文标题】:Pushing array data from api causes infinite loop 【发布时间】:2021-12-20 23:43:39 【问题描述】:

晚上好,我已经搜索了很长一段时间以来遇到的问题,但没有看到答案或帖子足够接近以获取有用的帮助。

我正在从 Firebase 中检索一些日期,我想将这些日期填充到我的 Vue 应用程序中的一些 ui 元素中。最终目标是让来自 Firebase 的每个日期与 Vue 应用程序中的相应月份相匹配并填充这些 ui 元素。到目前为止,我无法让数据正确显示而不会导致无限循环警告。

这是目前为止的代码:

data() 
    return 
      dates: [], <---- dates will fill this array from Firebase
      months: [ 
       name: 'Jan', createdOn: [] , 
       name: 'Feb', createdOn: [] , 
       name: 'Mar', createdOn: [] , 
       name: 'Apr', createdOn: [] , 
       name: 'May', createdOn: [] , 
       name: 'Jun', createdOn: [] , 
       name: 'Jul', createdOn: [] , 
       name: 'Aug', createdOn: [] , 
       name: 'Sept', createdOn: [] , 
       name: 'Oct', createdOn: [] , 
       name: 'Nov', createdOn: [] , 
       name: 'Dec', createdOn: [] , 
     ]
    ;
,
methods: 
 logNewDate() 
  let mons = this.months
  let dates = this.dates
  dates.forEach(date => 
    if(!mons[0].createdOn.includes(dates)) 
     mons[0].createdOn.push(date.createdOn)
    
  )
    console.log(mons[0].name, mons[0].createdOn)    
 ,

<div v-for="month in months" :key="month.name">
    <b-button 
    class="btn-circle btn-md" 
    >
       month.name 
    </b-button>
</div>
     logNewDate() 

起初,我将月份数组作为数组或月份字符串,但这只是导致 firebase 中的所有日期每个月重复循环,每次创建 5 个 ui 元素,但最初没有无限循环。我想下一步是在月份名称中包含一个数组集合,以便我可以将同一月份的多个日期存储在一起,因此数据函数中显示的月份属性的想法是将传入数据与正确的月份名称并用匹配的日期填充该对象 createdOn 数组。

到目前为止,我的 logNewDate 函数中的 forEach 循环将存储从 Firestore 显示的所有日期(目前只有 5 个用于测试目的),但是一旦所有五个日期都显示出来,它就会循环返回并一遍又一遍地添加所有五个日期。起初我使用 for in 循环迭代日期数组并将每个日期添加到 createdOn 数组,但这也导致了无限循环,这让我认为我在这段代码中的方法存在更根本的问题。

经过一番研究,我尝试使用 if(mons[0].createdOn.includes(date)) 检查只包括尚未出现的日期,而没有其他日期,但这不起作用。我也尝试在循环中添加 break 也没有效果。检索 Firebase 数据的函数目前在我创建的生命周期方法中。对于我现在正在测试的内容,我只希望这种情况发生一次。有人可以帮助我了解导致循环的原因以及如何修复它并防止这些错误继续发生吗?

我还想指出,我意识到在 forEach 循环中对数组索引进行硬编码并不是最佳做法。我最终希望它是动态的,等同于 Firebase 日期的月份。为了测试目的,我在示例中对它们进行了硬编码。

错误如下所示:

【问题讨论】:

请分享完整代码并添加您遇到的错误,以便我们为您提供更多帮助。 你的if(!mons[0].createdOn.includes(dates)) 没有检查被推送的东西,所以我认为这不会阻止重复。 我对整体问题有所猜测。也许您正在通过更改数据来响应数据更改通知。更改数据会导致数据更改通知,从而导致无限循环。 您的第一条评论实际上帮了我很多忙。我没有访问包含函数中的日期。一旦我这样做了,我就得到了我期望的日期,没有无限循环。但是它仍然会在控制台中打印 2 个数组,我不知道为什么。 你的意思是你不知道为什么logNewDate 被调用了两次?我不知道 Vue.js,但我猜它与它的渲染方式有关。 【参考方案1】:

Prabir 提出了一个很好的观点。对我有用的解决方案涉及使用嵌套的 for-in 循环。

一旦进入访问传入日期的内部循环,我将日期字符串转换为日期对象,将这些字符串缩短为缩短的月份名称,然后使用=== 检查这些新月份字符串是否匹配我在月份对象中预设的那些。

这是我的最终代码:

for(let i in this.months) 
    for(let j in this.incomingDates) 
        var dates = new Date(this.incomingDates[j].createdOn);
        const shortMonth = dates.toLocaleString('default',  month: 'short' );
        if(shortMonth === this.months[i].name) 
            this.months[i].createdOn.push(shortMonth);
            console.log(this.months[i].name, this.months[i].createdOn);
        
    

【讨论】:

以上是关于从 api 推送数组数据会导致无限循环的主要内容,如果未能解决你的问题,请参考以下文章

从孩子设置上下文会导致无限调用循环

从nib实例化UIView会导致无限循环问题

ReactJS fetch 导致无限循环

Angular 7:从订阅内部调用 ChangeDetectorRef detectChanges() 会导致无限循环

为啥这会导致无限请求循环?

为啥这会导致无限请求循环?