JavaScript函数运行无反应:异步操作和同步操作的差异
可能是因为第一个函数中的代码需要等待异步操作完成后才能执行,而第二个函数中的代码是同步执行的。可以尝试加上 async/await,或者将第一个函数的代码放在一个异步函数中执行。
第一个函数中,fetch 方法是异步的,它会返回一个 Promise 对象,表示最终会返回数据,但是数据可能需要一些时间才能获取到。在 Promise 对象解析之前,then 方法中的代码不会执行。
第二个函数中,Object.defineProperty 方法是同步的,它会立即改变 fileInput.files 的值,因此 change 事件也会立即触发。
解决方案:
- 使用 async/await:可以在第一个函数中使用 async/await 语法来等待异步操作完成,然后再执行后续代码。
- 将代码放在异步函数中:可以将第一个函数中的代码放在一个异步函数中,并使用 Promise 对象来处理异步操作。
示例代码:
// 使用 async/await
async function sendThumbnail2ControlNet() {
// 获取 <img> 元素
let imgThumbnail = document.querySelector('#thumbnail-container > img');
// 获取图片数据并转换为 Blob 对象
const blob = await fetch(imgThumbnail.src).then(response => response.blob());
// 将 Blob 对象转换为 File 对象
const dataTransfer = new DataTransfer();
dataTransfer.items.add(new File([blob], 'image.jpg', { type: blob.type }));
const fileList = dataTransfer.files;
// 获取需要上传图片的 <input type='file'> 元素
const fileInputs = document.querySelectorAll('#controlnet [id*='txt2img_controlnet_'] div.image-container > div > input[type='file']');
const indices = [0, 2, 4]; // 需要上传图片的 <input type='file'> 元素的索引 这里分别对应ControlNet 设置为3个的时候的 1 2 3 图片上传区域
indices.forEach(index => {
const fileInput = fileInputs[index];
const descriptor = Object.getOwnPropertyDescriptor(fileInput, 'files');
if (descriptor !== undefined && descriptor.configurable === true) {
Object.defineProperty(fileInput, 'files', { value: fileList });
}
// 触发 <input type='file'> 的 change 事件
const event = new Event('change', { bubbles: true });
fileInput.dispatchEvent(event);
});
}
// 将代码放在异步函数中
function sendThumbnail2ControlNet() {
// 获取 <img> 元素
let imgThumbnail = document.querySelector('#thumbnail-container > img');
// 获取图片数据并转换为 Blob 对象
fetch(imgThumbnail.src)
.then(response => response.blob())
.then(blob => {
// 将 Blob 对象转换为 File 对象
const dataTransfer = new DataTransfer();
dataTransfer.items.add(new File([blob], 'image.jpg', { type: blob.type }));
const fileList = dataTransfer.files;
// 获取需要上传图片的 <input type='file'> 元素
const fileInputs = document.querySelectorAll('#controlnet [id*='txt2img_controlnet_'] div.image-container > div > input[type='file']');
const indices = [0, 2, 4]; // 需要上传图片的 <input type='file'> 元素的索引 这里分别对应ControlNet 设置为3个的时候的 1 2 3 图片上传区域
indices.forEach(index => {
const fileInput = fileInputs[index];
const descriptor = Object.getOwnPropertyDescriptor(fileInput, 'files');
if (descriptor !== undefined && descriptor.configurable === true) {
Object.defineProperty(fileInput, 'files', { value: fileList });
}
// 触发 <input type='file'> 的 change 事件
const event = new Event('change', { bubbles: true });
fileInput.dispatchEvent(event);
});
});
}
通过使用 async/await 或者将代码放在异步函数中,可以确保异步操作完成后再执行后续代码,从而解决函数运行无反应的问题。
原文地址: https://www.cveoy.top/t/topic/owg5 著作权归作者所有。请勿转载和采集!