簡體   English   中英

如何在循環中放入async-await? 不工作

[英]How to put async-await in a loop? Not working

我使用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紋理

設置image.src后立即讀取image.height image.src導致0為高度。 設置src您應該等待加載圖像。 沒有承諾await加載圖像。 相反,它確實有一個名為onload的回調:

let img = new Image();
img.onload = function() { console.log("Height: " + this.height); }
img.src = "...";

嘗試使用map函數而不是for循環,將nimgs轉換為數組並使用map函數,如下所示:

async function load_imgs(label, nimgs) {

    await Promise.all(nimgs.map(async (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);

        })
    }))
}

請參閱以下說明: 使用async / await和forEach循環

有關更多信息,請參閱此文章: https//lavrton.com/javascript-loops-how-to-handle-async-await-6252dd3c795/

你的建議是宣布的不良做法。

“等待內部循環”不是一個好習慣。

理論上,你不能在循環的每次迭代中等待異步操作。 相反,您必須聲明所有異步操作,然后等待。

我認為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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM