CreateJS / PreloadJS

PreloadJS makes preloading assets & getting aggregate progress events easier in JavaScript. It uses XHR2 when available, and falls back to tag-based loading when not.
http://createjs.com/
MIT License
2.88k stars 764 forks source link

LoadQueue.remove may throw error in some condition #251

Open Z2Y-zz opened 6 years ago

Z2Y-zz commented 6 years ago

the following code throw error null is not an object (evaluating 'loadItem.id')

... loadItem = this._loadQueueBackup[i].getItem(); if (loadItem.id == item || loadItem.src == item) { this._loadQueueBackup.splice(i, 1)[0].cancel(); break; } ...

lannymcnie commented 6 years ago

This seems to indicate that the loadItem is null. Do you have more context you can provide?

Z2Y-zz commented 6 years ago

it hanppens when i remove some loaded items, now i changed to use removeAll. i don't know why the loaditem is null, maybe it should be checked before remove it ...
while (_cachedFiles.length > MAX_CACHE_FILE_SIZE) { queue.remove(_cachedFiles.shift()) } ...

remiX- commented 6 years ago

So I've been getting this as well and it's been annoying me.

I've had it happen in the loadQueuebackup removal section and currentLoads removal section. It seems that one of the items is null all round including the _item var in which it errors in the if as loadItem is null.

It still removes the actual image from being loaded in the end as it removes it from loadQueue or loadQueueBackup - but the main problem is that the image still actually downloads in the background (can see in the network tab).

That is my main issue at the moment and I hope there can be a fix for it asap?

Here's a screenie showing an item in the loadQueueBackup being null (just the listener section but _item is null too -> loadItem being null capture

nsmithdev commented 6 years ago

I'm having this same problem when I use Fiddler to simulate failed asset (sound) downloads. I do not have problems with 404 responses but if I do a redirect or some of the other odd stuff peoples firewalls do respond with a 200 html/text or redirect I get a null object loaded and the next time I call remove it errors out. I'm testing in Chrome right now.

nsmithdev commented 6 years ago

I'm using Chrome and it's attempting to download .mp3 files via XHR requests. PreLoader was built from master branch yesterday so all recent patches are applied.

If the download fails with a status code defined as an error below the item can be removed from the queue without a problem. https://github.com/CreateJS/PreloadJS/blob/master/src/preloadjs/net/XHRRequest.js#L397

If the download fails with some 302 redirect to html or 200 and html/text I receive:

Uncaught (in promise) DOMException: Unable to decode audio data

That seems to leave the request still somewhat active or at least still in the (_currentLoads) queue.

Then what happens is the next time remove is called it iterates through the items removing the item specified. When the item is removed from the second loop it calls cancel. The details of cancel can be seen in the second photo. Basically it sets the item value to null. So when it get's to the third loop the item value is null and the if statement generates an error vs removing the item.

preloadjs1

On the second loop of (3) Remove it calls (2) Cancel which calls (1) Destroy

preloadjs2

nsmithdev commented 6 years ago

This is a possible solution. It assumes all objects with null item have already been disposed. https://github.com/nsmithdev/PreloadJS/commit/0fe44a0e6a377a3fef69eab6b96a3abc7c86d314

TrueXakeP commented 4 years ago

Simple

var q = new createjs.LoadQueue(false);
q.loadFile({id:'goog', src:"http://google.com/", type: createjs.Types.HTML});
// q.setPaused(true); // doesn't matter
q.loadFile({id:'duck', src:"http://duck.com/", type: createjs.Types.HTML});
q.remove('duck'); // << here

leads to TypeError: loadItem is null at https://github.com/CreateJS/PreloadJS/blob/eab00cf50fe2f6993c75e04ad7f7e5e9c9e9f083/lib/preloadjs.js#L5049