block by migurski 3178499

Image Queue

Full Screen

index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<title>Image Queue</title>
    <script src="image-queue.js" type="application/javascript"></script>
</head>
<body>

    <script type="application/javascript">
    <!--
    
        var queue = ImageQueue();
        
        function getOnloaded(msg)
        {
            return function(err, img)
            {
                if(err == undefined)
                {
                    console.log('on loaded', msg, img);
                    document.body.appendChild(img);
                
                } else {
                    console.log('error in', msg, err);
                }
            }
        }
        
        queue.add('//linode.teczno.com/nothing-to-see-here', getOnloaded('Nothing #0'));
        queue.add('//linode.teczno.com/loris.php?delay=1&i=1', getOnloaded('Loris #1'));
        queue.add('//linode.teczno.com/loris.php?delay=2&i=2', getOnloaded('Loris #2'));
        queue.add('//linode.teczno.com/loris.php?delay=3&i=3', getOnloaded('Loris #3'));
        queue.add('//linode.teczno.com/loris.php?delay=1&i=4', getOnloaded('Loris #4'));
        queue.add('//linode.teczno.com/loris.php?delay=2&i=5', getOnloaded('Loris #5'));
        queue.add('//linode.teczno.com/loris.php?delay=3&i=6', getOnloaded('Loris #6'));
        
        queue.process();
        
        queue.cancel('//linode.teczno.com/loris.php?delay=1&i=4');
        queue.cancel('//linode.teczno.com/loris.php?delay=3&i=6');
        
        setInterval(function() { queue.process() }, 500);
    
    //-->
    </script>

</body>
</html>

image-queue.js

function ImageQueue()
{
    var closedRequests = {},
        queueList = [],
        queueByHref = {},
        numOpenRequests = 0,
        openRequests = {};
    
    function addImage(href, onload)
    {
        var request = {href: href, onloaded: onload};
        
        queueList.push(request);
        queueByHref[request.href] = request;
    }

    function cancelLoad(href)
    {
        // If the request is open, close it.

        if(href in openRequests)
        {
            // If the image is not yet loaded, prevent it from loading.

            if(closedRequests[href] == undefined)
            {
                openRequests[href].img.onload = function() {};
                openRequests[href].img.onerror = function() {};
                openRequests[href].img.src = "about:";
                openRequests[href].img = null;
            }
            
            delete openRequests[href];
            numOpenRequests--;
        }

        // Mark the image null in the queue so it will be skipped.

        if(href in queueByHref)
        {
            // get the href out of the queue
            delete queueByHref[href];
        }
    }
    
    function prioritizeQueue(pattern)
    {
        var sortFunction = function(r1, r2)
        {
            return Number(Boolean(r2.href.match(pattern))) - Number(Boolean(r1.href.match(pattern)));
        }
    
        queueList.sort(sortFunction);
    }

   /**
    * Request up to 4 things from the queue, skipping blank items.
    */
    function processQueue()
    {
        while(numOpenRequests < 4 && queueList.length > 0)
        {
            var href = queueList.shift().href;

            if(href in queueByHref)
            {
                loadImage(queueByHref[href]);
                openRequests[href] = queueByHref[href];
                delete queueByHref[href];                        
                numOpenRequests++;
            }
        }
    }
    
    function loadImage(request)
    {
        request.img = new Image();            

        request.img.onload = function()
        {
            request.onloaded(undefined, request.img);
            closedRequests[request.href] = Date.now();
            cancelLoad(request.href);
        }

        request.img.onerror = function(error)
        {
            request.onloaded(error, request.img);
            closedRequests[request.href] = Date.now();
            cancelLoad(request.href);
        }

        request.img.src = request.href;
    }
    
    function queueState()
    {
        return [numOpenRequests, queueList.length];
    }

    return {add: addImage, cancel: cancelLoad, process: processQueue, prioritize: prioritizeQueue, state: queueState};
};