Один из способов - вернуть Promise
для каждого загружаемого вами изображения. Это обещание будет разрешать , или с точки зрения мирян: продолжаться, когда выполняется правильное условие, всякий раз, когда изображения были загружены. Это похоже на оператор return
, но вместо завершения функции вы переходите к следующему шагу.
Promise.all
- это метод конструктора обещаний, который принимает массив обещаний. Когда все обещания в массиве были заполнены (то есть вызван resolve
), сделайте что-нибудь со значениями всех обещаний.
const loadImage = (source) => new Promise(resolve => {
let img = new Image();
img.onload = function() {
resolve(img);
};
img.src = source;
});
const whenAllImagesAreLoaded = (...sources) => Promise.all(
sources.map(source => loadImage(source));
);
whenAllImagesAreLoaded('image-1.jpg', 'image-2.jpg').then((images) => {
images.forEach(image => {
console.log(image, ' is loaded');
});
});
Другой пример также с обещаниями в сочетании с синтаксисом async
/ await
, который останавливает выполнение до тех пор, пока обещание, которое вы ожидаете, не будет выполнено.
Это открывает, например, возможность загружать изображения один за другим другой, после загрузки предыдущего изображения.
async function loadImagesSequentially(...sources) {
for (const source of sources) {
let image = await loadImage(source);
console.log(image, ' is loaded');
}
}
Оба метода дают вам лучший контроль над обработкой условий гонки или полностью устраняют их. Я бы посоветовал вам практиковаться как можно больше с обещаниями. Это очень мощный инструмент в вашем JavaScript наборе инструментов.
Если у вас есть какие-либо вопросы, пожалуйста, дайте мне знать.