【问题标题】:Doing fetch statements inside loop javascript async-await在循环中执行 fetch 语句 javascript async-await
【发布时间】:2021-06-04 23:04:03
【问题描述】:

好的,所以我尝试在 for 循环中执行异步等待以进行获取,最后将结果附加到所见即所得。当用户在编辑器中粘贴并循环图像以保存在我的服务器上时,我正在获取剪贴板数据。首先它通过 fetch() 从图像的 url 中获取 blob,然后再次使用 fetch() 将文件上传到我的服务器。这是代码:

    const forLoop = async _ => {
        for (let i = 0; i < imgNodeList.length; i++) {
            const img = imgNodeList[i];
            if (img.src) {
                let src = img.src;
                async function fetchBlob(src) {
                    const response = await fetch(src);
                    const blob = await response.blob();
                    return blob;
                }

                async function fetchUrl(file) {
                    const formData = newTokenData();
                    formData.append("image", file);
                    const response = await fetch('upload-image', { method: "POST", body: formData });
                    const json = await response.json();
                    return json;
                }

                fetchBlob(src).then(blob => {
                    let file = new File([blob], "new_file");
                    fetchUrl(file).then(json => {
                        console.log('image');
                        if (isJson(json)) {
                            let obj = JSON.parse(json);
                            if (obj.status == '200') {
                                tmp.querySelectorAll('img')[i].src = obj.url;
                            }
                        }
                    })
                });
            }
            console.log('loop end');
        }

        console.log('execute html');
        quill.clipboard.dangerouslyPasteHTML(index, tmp.innerHTML);
    }
    forLoop();

但是图像console.log在最后发生如下: 我该怎么做才能让代码等待 fetch inside 循环结束并在整个循环结束后在编辑器中执行粘贴操作。

【问题讨论】:

  • 您不能让for 循环等待。它是一个简单的for 循环,不注意循环体中的异步行为。您可以将循环体收集到一个单独的 async 函数中,然后将调用它的 Promise 实例收集到一个数组中,然后在循环后使用 Promise.all() 等待它们全部解决。
  • async/await 编码与.then() 编码混合并不是一个好主意;使用其中一个。

标签: javascript asynchronous async-await fetch


【解决方案1】:

我建议你不要混用.then's 和awaits;使用其中一种。混合编码风格使得跟踪执行顺序以及什么会做什么变得更加困难。以fetchBlob(src) 开头的 12 行是创建一个承诺,但实际上并没有等待它。

相反,您应该将这些行更改为:

const blob = await fetchBlob(src);
let file = new File([blob], "new_file");
const json = await fetchUrl(file);
console.log('image');
if (isJson(json)) {
  let obj = JSON.parse(json);
  if (obj.status == '200') {
    tmp.querySelectorAll('img')[i].src = obj.url;
  }
}

提醒一下,await 关键字只能在 async 函数中使用,因此请确保周围的函数是 async 函数。

通过这些修改,for 循环将在移动到 i 的下一个值之前等待,因此在到达 console.log('execute html') 之前将等待

【讨论】:

  • 它给出了const blob = await fetchBlob(src) 的错误。错误:Uncaught SyntaxError: Unexpected reserved word
  • 你能仔细检查一下周围的函数是一个异步函数吗?即,它必须是const forLoop = async _ =&gt; {,而不是const forLoop = _ =&gt; {(我假设您没有添加任何问题中未提及的额外功能)
  • 感谢我不得不将其更改为循环上的异步。你能在答案中提到,然后把它标记为正确
猜你喜欢
  • 1970-01-01
  • 2017-04-29
  • 2016-02-04
  • 2020-11-21
  • 2019-07-16
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多