【问题标题】:Fetch only returning last item in loop仅获取返回循环中的最后一项
【发布时间】:2020-01-06 14:07:27
【问题描述】:

我觉得我在这里遗漏了一些非常基本的东西......总结是我有一组 10 张卡片,对应于我网站上的 10 个不同的集合。每张卡片都有一个图像元素。我想用一张新卡替换那张卡,其中图像的来源和其他一些项目已经改变(而且我还添加了动画)。

问题是我从另一个站点 (website/collectionName/configs.ini) 获取的新图像源的获取仅适用于循环中的最后一张卡。

let cardsOnly = document.createElement("div");
cardArray = document.querySelectorAll('.cards');
cardArray.forEach(function(card) {
    //do a bunch of stuff to the card like add title and remove old classes
    card.appendChild(cardTitleDiv);
    collectionName = //grabbed from this page
    bgImage = document.createElement("img");
    let configWebsite = website/collectionName/configs.ini

    const request = async () => {
        const response = await fetch(configWebsite)
        const text = await response.text() //so now I have the text from the config website
        newImgSource = //extracted from text
        console.log(collectionName + " " + newImgSource);
        bgImage.setAttribute("src", newImgSource);
        console.log(bgImage);
        card.appendChild(bgImage);
    }
    request();
    //do a bunch of other stuff to the card like add description div
    card.appendChild(descriptionDiv);
    cardsOnly.appendChild(card); //add all cards to cardsOnly div
}
//append the cardsOnly div to my wrapper on the page. 

当页面加载时,卡片都有正确的标题、正确的描述,这是奇怪的部分……第一个 console.log,对于数组中的 10 个卡片中的每一个,它都输出了正确的 collectionName以及我刚刚提取并提取的正确的新图像源....

但当我查看cardsOnly div 时,唯一带有<img> 元素的卡片是最后一张卡片。并且在 request()... 中的 console.log(bgImage) 一直输出与最后(第 10 个)卡片相对应的 <img> 元素。


我的控制台如下所示:

collection1: correct new image source for collection 1
<img> element for collection 10 with correct img src for collection 10

collection2: correct new img src for collection 2
<img> element for collection 10 with correct img src for collection 10

etc..
etc.. 

为什么会这样?

【问题讨论】:

  • request 是异步的,但您从不等待它。请咨询this

标签: javascript html fetch


【解决方案1】:

可能是范围界定问题。 bgImage 从未被声明过,因此具有函数范围,就像用 var 声明的变量一样。这意味着您在每次迭代中都在使用相同的bgImage。您应该使用 let 以便获得块范围。

let bgImage = document.createElement("img");

【讨论】:

  • 进步!这实际上准确地创建了所有图像元素......它只是将它们全部放在最后一张卡片上。我会尝试重构,希望这就是我搞砸的全部
  • 这可能是因为异步。您正在循环体内执行card.appendChild(cardTitleDiv);,但您在异步函数中添加了下一个元素。所以发生的事情是你首先添加 n 个 div,直到异步函数运行,然后你将 n 个图像添加到最后一个 div。您应该在函数中同时执行这两项操作。
  • 所以在 request() 中,我只对源进行 fetch 并为 bgImage 设置 src 属性,然后在调用 request() 后附加图像,一切似乎都正常。十分感谢你的帮助!您的原始答案基本上解决了所有问题:D
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 2019-05-06
  • 1970-01-01
  • 2020-05-06
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 2021-12-25
相关资源
最近更新 更多