javascript - 如何将异步等待放入循环中?不工作

标签 javascript node.js asynchronous

我正在使用 ml5 对机器学习项目中的图像进行分类。该程序从 json 文件中获取图像路径和类型,然后将每个图像添加到 ml5 分类器,然后用于训练机器学习模型。

当我尝试仅将一张图像加载到分类器中时,它可以正常工作(但它不会创建模型,因为它至少需要 2 张图像才能进行训练)。但是,当我尝试在 for 循环中将这些图像添加到分类器时,出现错误。

文件由 load_data() 函数加载,该函数由按钮触发。 load_data() 调用 load_imgs(label, nimgs),其中 label 是文件夹,nimgs 是其中的图像数量。 load_imgs(label, nimgs) 然后遍历 nimgs 并获取数据(json 文件)中指定的图像路径,从中生成一个图像元素,然后将其添加到分类器中。

这些函数定义为:

    async function load_imgs(label, nimgs) {

        const forLoop = async _ => {
            for (let i = 0; i < nimgs; i++) {
                const imageData = await data.children[label].children[i]
                const image = document.createElement("img")
                image.src = imageData.path
                const type = await imageData.type;
                await classifier.addImage(image, type, (res) => {
                    console.log("image added to classifier", image.height);
                    console.log(image);

                })

            }
        }
        await forLoop()
    }

    function load_data() {
        (async() => {
            try {
                await load_imgs(0, googleImages);
                await load_imgs(1, amazonImages);
                await load_imgs(2, paypalImages);
                await load_imgs(3, facebookImages);
                await load_imgs(4, dropboxImages);
                console.log("images added");

            } catch (error) {
                console.log(error);
            }
        })();

    }

为此代码生成的日志是:

    index-train.html:106 Live reload enabled.
    train.js:84 json loaded
    train.js:69 Model loaded
    train.js:38 image added to classifier 0
    train.js:39 <img src=​"all_data/​google/​google_85.png">​
    train.js:107 Error: Requested texture size [0x0] is invalid.
        at re (tf-core.esm.js:17)
        at Wi (tf-core.esm.js:17)
        at Gi (tf-core.esm.js:17)
        at t.createUnsignedBytesMatrixTexture (tf-core.esm.js:17)
        at t.acquireTexture (tf-core.esm.js:17)
        at t.acquireTexture (tf-core.esm.js:17)
        at t.uploadToGPU (tf-core.esm.js:17)
        at t.getTexture (tf-core.esm.js:17)
        at t.fromPixels (tf-core.esm.js:17)
        at t.fromPixels (tf-core.esm.js:17)

我希望这会在 classifier.addImage 的函数回调中打印图像的实际大小,但相反,它得到的是 0x0 纹理

最佳答案

您的建议是公认的不良做法。

“将等待放入循环”不是一个好习惯。

理论是您不得在循环的每次迭代中等待异步操作。相反,您必须声明所有异步操作,然后等待。

这个例子来自ES Lint我认为可以满足您的需求。

此规则的正确代码示例:

async function foo(things) {
  const results = [];
  for (const thing of things) {
    // Good: all asynchronous operations are immediately started.
    results.push(bar(thing));
  }
  // Now that all the asynchronous operations are running, here we wait until they all complete.
  return baz(await Promise.all(results));
}

此规则的错误代码示例:

async function foo(things) {
  const results = [];
  for (const thing of things) {
    // Bad: each loop iteration is delayed until the entire asynchronous operation completes
    results.push(await bar(thing));
  }
  return baz(results);
}

关于javascript - 如何将异步等待放入循环中?不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57072484/

相关文章:

javascript - 如何根据数据库值制作 JavaScript 时钟

javascript - 根据日期时间或一天中的时间更改 CSS

javascript - Facebook Javascript SDK : Event auth. sessionChange 和 auto.logout 仅在页面刷新时触发

javascript - 异步的each立即打印出所有元素

javascript - AngularJS 不解析从指令动态加载的数据

angularjs - 这种类型的多属性过滤称为什么? (见截图)

Node.Js:资源解释为字体但使用 MIME 类型 text/html 传输

javascript - 如何计算 react Discord js

javascript - 如何防止 ASP.net PageMethod 调用阻止其他 javascript 函数调用

Angular 2 变化检测与 observables