首页 > 解决方案 > fetch 语句完成后的 Javascript 执行语句

问题描述

在这里,我将blob urls存在于调用的数组中转换imgs[]base64 data,然后将 base 64 数据推送到名为imgsPost[]. 将所有 base64 数据推入数组后,我想在函数中使用该数组。

let imgsPost = [];
let imgs = ["bloburl1", "bloburl2", "bloburl3", "bloburl4"];
for (let i = 0; i < imgs.length; i++) {
    fetch(imgs[i].src)
        .then(res => {
            if (!res.ok) {
                throw Error(res.statusText);
            }
            return res.blob();
        })
        .then(data => {
            let tempBlob = data;
            let reader = new FileReader();
            reader.readAsDataURL(tempBlob);
            reader.onloadend = function () {
                let base64data = reader.result;
                imgsPost.push(base64data);
            }
        })
        .catch(error => {
            console.error('Error:', error);
        })
}
        //After all execution
        foo($imgsPost);

现在该函数首先使用一个空数组执行。所有其他代码都在运行。

标签: javascriptimageasynchronouspromisefetch

解决方案


这是一个异步问题。您告诉 4 次在结果到达执行一些代码,然后在结果到达foo($imgsPost); 之前执行。

使用的解决方案Promise.all

const imgs = [
    'https://www.gravatar.com/avatar/5ac4d13d84719bf7f11cfd9ba7e0b15b?s=32&d=identicon&r=PG&f=1',
    'https://www.gravatar.com/avatar/f1f3cf96ee354f414ec58c2824f80938?s=32&d=identicon&r=PG&f=1'
];

const promises = imgs.map(img => fetch(img)
    .then(res => {
        if (!res.ok) {
            throw Error(res.statusText);
        }
        return res.blob();
    })
    .then(data => {
        const reader = new FileReader();
        reader.readAsDataURL(data);
        return new Promise(resolve => reader.onloadend = () => resolve(reader));
    })
    .then(({ result }) => result)
);

const foo = console.log;

Promise.all(promises).then(foo).catch(error => {
    console.error('Error: ', error);
});

您还可以使用async/await语法,它提供了非常有用的语法糖而不是承诺,并使代码看起来像它是同步的。


推荐阅读