简体   繁体   English

从异步 function 获取 boolean 值,然后验证 IF ELSE 条件

[英]Get a boolean value from async function and then validate an IF ELSE condition

This is the code snippet.这是代码片段。 Here, I want to check if an image's width OR heigh exceeds 100, I want to return true so that I can restrict uploading such file/image to the array.在这里,我想检查图像的宽度或高度是否超过 100,我想返回 true 以便我可以限制将此类文件/图像上传到数组。

const getHeightWidth = async () => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    await reader.addEventListener('load', async (e) => {
        const image = new Image();
        image.src = reader.result;
        await image.addEventListener('load', function () {
            const { height, width } = this;
            invalidFileHeightWidth = !!((height !== 100 || width !== 100));
            return invalidFileHeightWidth;
        });
    });
};

I tried Promise.resolve as well as a direct return statement but no luck so far我尝试了 Promise.resolve 以及直接返回语句,但到目前为止没有运气

I would break this into five separate functions:我会把它分成五个独立的功能:

  1. loadImageFromFile ~ a Promise that loads by filename using a FileReader loadImageFromFile ~ Promise使用FileReaderfilename加载
  2. loadImage ~ a Promise that sets the src of an Image object loadImage ~ 一个Promise设置Image object 的src
  3. loadImageFromFile ~ combines the two above functions into one call loadImageFromFile ~ 将以上两个函数合并为一个调用
  4. isValidSize ~ validates the width/height of a given image isValidSize ~ 验证给定图像的宽度/高度
  5. previewFile ~ an event handler for listening to a file input previewFile ~ 用于侦听文件输入的事件处理程序

 const previewFile = async () => { const preview = document.querySelector('img'); const file = document.querySelector('input[type=file]').files[0]; const image = await loadImageFromFile(file); const isValid = isValidSize(image); console.log(`Image size valid: ${isValid }`); preview.src = image.src; // Update preview }; const loadImageFromFile = async (file) => { const reader = await readFile(file); return loadImage(reader.result); }; const readFile = async (file) => new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.readAsDataURL(file); fileReader.addEventListener('load', (e) => resolve(fileReader)); fileReader.addEventListener('error', (e) => reject(e)); }); const loadImage = async (imageData) => new Promise((resolve, reject) => { const image = new Image(); image.src = imageData; image.addEventListener('load', function (e) { resolve(this); }); image.addEventListener('error', function (e) { reject(e); }); }); const isValidSize = (image) => { const { height, width } = image; return width === 100 && height === 100; };
 <input type="file" onchange="previewFile()" /><br /> <img src="" height="100" alt="Image preview" />

If you want one giant monolithic function, you can try:如果你想要一个巨型单片function,你可以尝试:

Note: You are using this to only check if the image is valid.注意:您使用它来仅检查图像是否有效。 You will need to load the image again, if you want to do more with the image.如果您想对图像执行更多操作,则需要再次加载图像。 This is why the first example is a better choice.这就是为什么第一个例子是更好的选择。 It separates validation from the loading.它将验证与加载分开。

 const preview = document.querySelector('img'); const previewFile = async () => { const preview = document.querySelector('img'); const file = document.querySelector('input[type=file]').files[0]; const isValid = await isValidSize(file); console.log(`Image size valid: ${isValid }`); }; const isValidSize = async (file, expectedWidth = 100, expectedHeight = 100) => new Promise((resolve, reject) => { const fileReader = new FileReader(); fileReader.readAsDataURL(file); fileReader.addEventListener('load', (e) => { const image = new Image(); image.src = fileReader.result; image.addEventListener('load', function (e) { const { height, width } = this; resolve(width === expectedWidth && height === expectedHeight); }); image.addEventListener('error', function (e) { reject(false); }); preview.src = image.src; // This is now coupled... }); fileReader.addEventListener('error', (e) => reject(false)); });
 <input type="file" onchange="previewFile()" /><br /> <img src="" height="100" alt="Image preview" />

If you want to use async / await , you will want to wrap the events inside a Promise constructor.如果您想使用async / await ,您需要将事件包装在Promise构造函数中。

Below is a simple working example, select a image file and it will give you the size.下面是一个简单的工作示例,select 一个图像文件,它会给你大小。

 function getFileSize(file) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = e => { const image = new Image(); image.onload = e => resolve([image.width, image.height]); image.onerror = e => reject(e); image.src = reader.result; } reader.onerror = e => reject(e); reader.readAsDataURL(file); }); } document.querySelector('input').addEventListener('change', async e => { const span = document.querySelectorAll('span'); const size = await getFileSize(e.target.files[0]); span[0].innerText = size[0]; span[1].innerText = size[1]; });
 span { font-weight: bold; }
 <input type="file" accept="image/png, image/gif, image/jpeg"/> <div>width: <span></span></div> <div>height: <span></span></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM