Существует ряд различных алгоритмов для решения этой проблемы, и часть процесса выбора зависит от того, какое именно поведение вы хотите. Исходя из вашего описания, звучит так, будто вы хотите, чтобы изображение отображалось сразу после загрузки, но никогда не перезаписывало изображение, которое появилось после него и уже было отображено. Это означает, что если изображения запрашиваются в порядке 1,2,3, но поступают в порядке 2,1,3, то вы будете показывать изображение 2, затем 3 и никогда не показывать 1.
Если предположить, что это желаемый алгоритм, то довольно простой способ сделать это - просто назначить каждому запросу порядковый номер и просто отслеживать последний порядковый номер, который вы показали. Всякий раз, когда какое-либо изображение завершает загрузку, вы проверяете, является ли его порядковый номер выше последней отображаемой последовательности. Если нет, вы не показываете его, потому что это старое изображение, которое превзошло новое изображение. Если это так, то вы показываете его и обновляете номер lastShownSequence
до порядкового номера этого изображения. Для этого типа алгоритма требуются две устойчивые переменные для отслеживания номера lastShownSequence и номера nextSequenceNumber.
Вот пример реализации кода:
var lastShownImage = 0;
var nextSequenceNumber = 1;
// url is image url
// elem is image element in the page to replace with newly loaded image element
function loadImage(url, elem) {
let imageSequenceNumber = nextSequenceNumber++;
let img = new Image();
img.onload = function() {
// image loaded now
// see if we should display it or not
if (imageSequenceNumber > lastShownImage) {
// hide current image so there's never any flashing of two images
elem.style.display = "none";
// record the sequence number we are showing
lastShownImage = imageSequenceNumber;
// insert new image
let parent = elem.parentNode;
parent.insertBefore(img, elem);
// remove previous image
parent.removeChild(elem);
}
};
img.src = url;
}
Если вы не хотите, чтобы lastShownImage
или sequenceNumber
были открыты, как эта, то их можно инкапсулировать либо в IIFE, либо в экземпляр класса, который вы создаете, но, поскольку я не вижу как именно вы будете использовать это в своем коде или посмотреть, нужна ли вам более обобщенная реализация с несколькими экземплярами, я не добавил для этого никаких дополнительных усложнений.