Skip to content

Instantly share code, notes, and snippets.

@migurski
Created July 25, 2012 20:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save migurski/3178499 to your computer and use it in GitHub Desktop.
Save migurski/3178499 to your computer and use it in GitHub Desktop.
Image Queue
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};
};
<!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('http://linode.teczno.com/nothing-to-see-here', getOnloaded('Nothing #0'));
queue.add('http://linode.teczno.com/loris.php?delay=1&i=1', getOnloaded('Loris #1'));
queue.add('http://linode.teczno.com/loris.php?delay=2&i=2', getOnloaded('Loris #2'));
queue.add('http://linode.teczno.com/loris.php?delay=3&i=3', getOnloaded('Loris #3'));
queue.add('http://linode.teczno.com/loris.php?delay=1&i=4', getOnloaded('Loris #4'));
queue.add('http://linode.teczno.com/loris.php?delay=2&i=5', getOnloaded('Loris #5'));
queue.add('http://linode.teczno.com/loris.php?delay=3&i=6', getOnloaded('Loris #6'));
queue.process();
queue.cancel('http://linode.teczno.com/loris.php?delay=1&i=4');
queue.cancel('http://linode.teczno.com/loris.php?delay=3&i=6');
setInterval(function() { queue.process() }, 500);
//-->
</script>
</body>
</html>
@zerostyle
Copy link

This is really elegant. Can you explain, or show and example of the prioritizeQueue method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment