Javascript 如何将async Wait放入循环中?不起作用
我在一个机器学习项目中使用ml5对图像进行分类。该程序从json文件中获取图像路径和类型,然后将每个图像添加到ml5分类器,然后用于训练机器学习模型 当我尝试只将一个图像加载到分类器中时,它工作正常(但是它不会创建模型,因为训练至少需要2个)。但是,当我尝试在for循环中将这些图像添加到分类器时,它会给我带来错误 文件由按钮触发的Javascript 如何将async Wait放入循环中?不起作用,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,我在一个机器学习项目中使用ml5对图像进行分类。该程序从json文件中获取图像路径和类型,然后将每个图像添加到ml5分类器,然后用于训练机器学习模型 当我尝试只将一个图像加载到分类器中时,它工作正常(但是它不会创建模型,因为训练至少需要2个)。但是,当我尝试在for循环中将这些图像添加到分类器时,它会给我带来错误 文件由按钮触发的load_data()功能加载load_data()调用load_imgs(label,nimgs)其中label是文件夹,nimgs是其中的图像数load_imgs(
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);
}
})();
}
异步函数加载\u imgs(标签,nimgs){
常量forLoop=async\ux=>{
for(设i=0;i 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)
index train.html:106已启用实时重新加载。
train.js:84 json加载
列车.js:69型装载
train.js:38图像添加到分类器0
火车站:39
train.js:107错误:请求的纹理大小[0x0]无效。
在re(tf core.esm.js:17)
在Wi(tf core.esm.js:17)
在Gi(tf core.esm.js:17)
在t.createUnsignedBytesMatrixture(tf core.esm.js:17)
在t.acquireTexture(tf core.esm.js:17)
在t.acquireTexture(tf core.esm.js:17)
在t.uploadToGPU(tfcore.esm.js:17)
at t.getTexture(tfcore.esm.js:17)
t.fromPixels(tf core.esm.js:17)
t.fromPixels(tf core.esm.js:17)
我希望这会在
分类器的函数回调中打印图像的实际大小。addImage
,但相反,它会在设置图像后立即读取图像。height
。src
会将0作为高度。设置src
后,应等待图像加载。没有承诺等待加载图像。相反,它有一个名为onload
的回调:
let img = new Image();
img.onload = function() { console.log("Height: " + this.height); }
img.src = "...";
尝试使用map函数而不是for循环,将nimgs转换为array并使用如下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 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);
}
此规则的错误代码示例:
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);
}
wait data.children[label].children[i]
data是加载到对象中的json。标签
表示在json中定义顺序的文件夹索引i
表示包含图像文件的本地路径的字符串添加image.onload
侦听器。image.src=imageData.path
并不表示图像已加载。可以help@lx1412谢谢你这一切就像是我手指上的一根刺。非常感谢image。onload
成功了,不过,谢谢,我也要试试这个