【问题标题】:Append to array in async for loop在异步 for 循环中追加到数组
【发布时间】:2022-02-14 00:24:19
【问题描述】:

我有这个函数,其中包含其他嵌套的异步函数。

我正在解压缩一个 zip 文件,然后将每个 HTMLImageElement 附加到一个数组中。

但是,数组是这样打印的

16 是我期望的正确数量的图像,但是当我console.log() 它们时它们是未定义的。

export async function fetchVisuals(TestID: number) {
    var zip = new JSZip();
    const res = await fetch('*DJANGO URL*', {
        body: JSON.stringify(TestID),
        method: 'POST'
    })
    let http_ok = res.ok
    const blob = await res.blob()
    var bufferPromise = await blob.arrayBuffer();
    zip.loadAsync(bufferPromise).then(async ({files}) => {
        const mediaFiles = Object.entries(files).filter(([fileName]) =>
            fileName.endsWith('.jpg'),
        );
        if (!mediaFiles.length) {
            throw new Error('No media files found in archive');
        }
        // I'm very confident the issue is to do with the below function
        let promiseArray = mediaFiles.map(function([,image]) {
            image.async('blob').then((blob: Blob | MediaSource) => {
                console.log("mediaFiles loop")
                const img = new Image();
                img.src = URL.createObjectURL(blob)
                console.log(img)
                return img
            })
        })
        Promise.all(promiseArray).then(function(resultsArray) {
            console.log(resultsArray)
        })
    })
}

我将每个图像的承诺映射到一个数组,然后在这个数组上执行Promise.all(),所以我不确定为什么它仍然以undefined 的形式返回。

mediaFiles.map()内部我做了一些打印,他们成功打印了img数据。

如何用HTMLImageElements 填充这个数组?

【问题讨论】:

  • 你忘了return image.async('blob')
  • @EmielZuurbier 是的,就是这样。休息后我又读了一遍,意识到我回到了image.async,就是这样......你的改变修复了它:)
  • 顺便说一句,使用const {files} = await zip.loadAsync(bufferPromise); 而不是.then(…),其他then 调用相同。你也忘了return(或awaitPromise.all(promiseArray)

标签: javascript arrays reactjs asynchronous


【解决方案1】:

你没有在 map 函数中返回你的承诺:

        let promiseArray = mediaFiles.map(function([,image]) {
            image.async('blob').then((blob: Blob | MediaSource) => {
                console.log("mediaFiles loop")
                const img = new Image();
                img.src = URL.createObjectURL(blob)
                console.log(img)
                return img
            })
        })

必须变成:


 // I'm very confident the issue is to do with the below function
        let promiseArray = mediaFiles.map(function([,image]) {
            /*just there : */ return image.async('blob').then((blob: Blob | MediaSource) => {
                console.log("mediaFiles loop")
                const img = new Image();
                img.src = URL.createObjectURL(blob)
                console.log(img)
                return img
            })
        })

对于你的第二个问题,你必须等待你的承诺并返回他们的结果:

export async function fetchVisuals(TestID: number) {
    var zip = new JSZip();
    const res = await fetch('*DJANGO URL*', {
        body: JSON.stringify(TestID),
        method: 'POST'
    })
    let http_ok = res.ok
    const blob = await res.blob()
    var bufferPromise = await blob.arrayBuffer();
    const {files} = await zip.loadASync(bufferPromise);
    const mediaFiles = Object.entries(files).filter(([fileName]) =>
        fileName.endsWith('.jpg'),
    );
    if (!mediaFiles.length) {
        throw new Error('No media files found in archive');
    }
    // I'm very confident the issue is to do with the below function
    let promiseArray = mediaFiles.map(function([,image]) {
        return image.async('blob').then((blob: Blob | MediaSource) => {
            console.log("mediaFiles loop")
            const img = new Image();
            img.src = URL.createObjectURL(blob)
            console.log(img)
            return img
        })
    })
    return await Promise.all(promiseArray);
}


【讨论】:

  • @Emial Zuubier 也提出了这个建议,并且已经解决了 :) 非常感谢
  • 我一定是在他发表评论时写下我的答案^^ 很高兴它对你有所帮助!
  • 有什么想法可以在调用fetchVisuals 时返回resultsArray
  • 我编辑了我的答案,应该没问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 2018-10-08
  • 2022-01-25
  • 2016-08-22
  • 2021-08-10
  • 2018-10-04
相关资源
最近更新 更多