我用jquery和一些基本的javascript构建了一个简单的tensorflow.js应用程序。
我有一个按钮,当点击时,它会禁用自己并切换一个旋转器图标,以指示模型正在执行其预测。预测完成后,恢复默认按钮。然而,从视觉上看,UI在浏览器上的行为并不是这样的。
演示:https://maksimdan.github.io/endpoints/models/pokename.htm
如果我们用同步睡眠函数代替预测,它的行为与预期一致。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
$("#raw-gen-button").click(async function(){
console.log("Generating new predictions...");
showButtonId("#generating-button");
await sleep(750);
// let predictions = await predict_model(5);
// addGeneratedNamesToUI(predictions);
showButtonId("#generate-button");
console.log("Finished generating new predictions...");
// console.log(predictions);
});
model.predict
函数是一个同步函数,这意味着await
关键字不会对它们产生影响,可以在调用model.predict
时删除await
关键字,然后在定义predict_model
函数时删除async
。
predict_model
函数是一个同步函数(像:let a = 1 + 1;
), "它"等到操作完成后再执行下一行代码。在你的情况下,该函数将阻塞主线程(UI线程),而它正在执行,这意味着你不能点击,更新DOM,运行动画…在你的浏览器上。
简单的想法是使predict_model
与setTimeout
函数成为async函数,setTimeout
将推送"content"到一个"队列",它不会锁定你的UI线程:
$("#raw-gen-button").click(async function(){
console.log("Generating new predictions...");
showButtonId("#generating-button");
const predictions = await new Promise((resolve) => { // wrap into a Promise to use await keyword
setTimeout(() => {
resolve(predict_model(5))
}, 100);
});
addGeneratedNamesToUI(predictions);
showButtonId("#generate-button");
console.log("Finished generating new predictions...");
console.log(predictions);
});