Created
July 25, 2012 20:33
-
-
Save migurski/3178499 to your computer and use it in GitHub Desktop.
Image Queue
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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}; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is really elegant. Can you explain, or show and example of the prioritizeQueue method?