I tried to do the same. I preloaded 12 audio and 12 image files in preparation for interactive actions based on them. I was getting the same problem (requests canceled).
I put together this routine that works for me (testing Chrome so far).
cacheLessonFiles: function (lessonWords, cacheImg, cacheAudio) { var fileName = '', img = {}, audio = {}, wordIDs = Object.keys(lessonWords) ; wordIDs.forEach(function (wordID) { if (cacheImg) { fileName = lessonWords[wordID].img || wordID; img = new Image(); img.onload = function () { console.log('cache: finished caching ' + this.src); }; img.src = "/img/" + fileName + imageSuffix; } if (cacheAudio) { fileName = lessonWords[wordID].saySpanish || wordID; audio = new Audio(); audio.onloadeddata = function () { console.log('cache: finished caching ' + this.src); }; audioArray.push({a: audio, f:"/audio/" + fileName + audioSuffix}); } }); setTimeout(loadAudio, AUDIO_LOAD_WAIT); },
The program simply downloads image files without special processing. Image files were more complex. Instead of just setting the source for all audio files in a loop, I populated the array with an audio element and its associated source file name (.mp3). Then I ran a self-naming timeout callback to process the array, pausing for 200 ms between requests.
function loadAudio () { var aud = audioArray.pop() ; aud.a.src = aud.f; if (audioArray.length > 0) { setTimeout(loadAudio, AUDIO_LOAD_WAIT); } }
One constant and one variable are inside the closure, but outside the cacheLessonFiles () method.
AUDIO_LOAD_WAIT = 200, audioArray = []
I tried a latency of less than 200 ms, but pending requests began to appear.
I would suggest that clients at the end of slower connections (I'm on the fiber) are likely to fail again, but this works well enough for my purposes.
source share