У меня есть код, который проверяет соотношение изображений. Это работает в 9 из 10 раз или даже чаще, но время от времени это не работает, потому что img.naturalWidth и img.naturalHeight возвращают 0. Я понимаю, что изображение не загружается в тот момент, когда я пытаюсь получить высота и ширина изображения, но я не знаю, почему это происходит редко. Код также находится внутри файла read.onload — решения, которое я нашел в большинстве онлайн-статей.
isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
return new Promise((resolve, reject) => {
const reader = new FileReader();
const img = new Image();
img.src = window.URL.createObjectURL(selectedFile);
reader.readAsDataURL(selectedFile);
reader.onload = () => {
const ratio = img.naturalWidth / img.naturalHeight;
resolve(ratio >= 1 && ratio <= 2);
};
reader.onerror = (error) => reject(error);
});
}
Любое решение или предложение приветствуется. Спасибо



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я думаю, что new FileReader() бесполезен и именно он стал причиной этой ошибки. Измените свой код следующим образом:
isValidFileRatio(selectedFile: Blob, width: number, height: number): any {
return new Promise((resolve, reject) => {
const img = new Image();
img.src = window.URL.createObjectURL(selectedFile);
img.onload = () => {
const ratio = img.naturalWidth / img.naturalHeight;
resolve(ratio >= 1 && ratio <= 2);
};
img.onerror = (error) => reject(error);
});
Проблема в том, что вы используете filereader.onload вместо image.onload.
Вот как бы я это решил:
Я бы использовал createImageBitmap вместо FileReader, Image или Canvas, которые потребовали бы сочетания обратных вызовов и обещаний.
Я также стараюсь, когда это возможно, вырваться из цепочки обещаний, синхронизируя большую часть своего собственного кода. таким образом, моя собственная функция не станет асинхронной, потому что что-то еще является асинхронным.
/**
* @param {{ width: number, height: number }} image
*/
function isValidFileRatio (image) {
const ratio = image.width / image.height
return ratio >= 1 && ratio <= 2
}
// Just to get a simple dummy image/png blob for demo
var blob = new OffscreenCanvas(300, 200).getContext('2d').canvas.convertToBlob()
blob
.then(createImageBitmap)
.then(isValidFileRatio)
.then(console.info)