Browse Source

Merge pull request #12434 from ngokevin/fileloader

have FileLoader merge multiple concurrent requests for the same url (fixes #10644)
Mr.doob 7 years ago
parent
commit
6af52d4614
1 changed files with 38 additions and 0 deletions
  1. 38 0
      src/loaders/FileLoader.js

+ 38 - 0
src/loaders/FileLoader.js

@@ -5,6 +5,8 @@
 import { Cache } from './Cache.js';
 import { DefaultLoadingManager } from './LoadingManager.js';
 
+var currentlyLoadingFiles = {};
+
 function FileLoader( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : DefaultLoadingManager;
@@ -39,6 +41,19 @@ Object.assign( FileLoader.prototype, {
 
 		}
 
+		// If file is already in process of loading, wait for it to load.
+		if ( currentlyLoadingFiles[ url ] !== undefined ) {
+
+			currentlyLoadingFiles[ url ].push( function () {
+
+				scope.load( url, onLoad, onProgress, onError );
+
+			} );
+
+			return;
+
+		}
+
 		// Check for data: URI
 		var dataUriRegex = /^data:(.*?)(;base64)?,(.*)$/;
 		var dataUriRegexResult = url.match( dataUriRegex );
@@ -131,6 +146,14 @@ Object.assign( FileLoader.prototype, {
 		} else {
 
 			var request = new XMLHttpRequest();
+
+			if ( Cache.enabled ) {
+
+				// Allow other file loaders to wait and subscribe on this request.
+				currentlyLoadingFiles[ url ] = [];
+
+			}
+
 			request.open( 'GET', url, true );
 
 			request.addEventListener( 'load', function ( event ) {
@@ -165,6 +188,21 @@ Object.assign( FileLoader.prototype, {
 
 				}
 
+				if ( Cache.enabled ) {
+
+					var duplicateRequests = currentlyLoadingFiles[ url ];
+
+					delete currentlyLoadingFiles[ url ];
+
+					// Tell other requests for the same file that the file has finished loading.
+					for ( var i = 0; i < duplicateRequests.length; i ++ ) {
+
+						duplicateRequests[i]( response );
+
+					}
+
+				}
+
 			}, false );
 
 			if ( onProgress !== undefined ) {