Bläddra i källkod

Loader: Add `abort()`. (#31276)

* Loader: Add `abort()`.

* EventDispatcher: Add `removeEventListeners()`.

* LoadingManager: Remove `dispose()`.

* Loaders: Recreate `AbortController`.

* LoadingManager: New abort approach.

* Clean up.

* Loaders: Add `AbortSignal.any()` fallback.

* LoadingManager: Add note about `AbortSignal.any()`.
Michael Herzog 9 månader sedan
förälder
incheckning
c3d0cd4a91
4 ändrade filer med 83 tillägg och 1 borttagningar
  1. 23 1
      src/loaders/FileLoader.js
  2. 23 0
      src/loaders/ImageBitmapLoader.js
  3. 14 0
      src/loaders/Loader.js
  4. 23 0
      src/loaders/LoadingManager.js

+ 23 - 1
src/loaders/FileLoader.js

@@ -55,6 +55,14 @@ class FileLoader extends Loader {
 		 */
 		 */
 		this.responseType = '';
 		this.responseType = '';
 
 
+		/**
+		 * Used for aborting requests.
+		 *
+		 * @private
+		 * @type {AbortController}
+		 */
+		this._abortController = new AbortController();
+
 	}
 	}
 
 
 	/**
 	/**
@@ -121,7 +129,7 @@ class FileLoader extends Loader {
 		const req = new Request( url, {
 		const req = new Request( url, {
 			headers: new Headers( this.requestHeader ),
 			headers: new Headers( this.requestHeader ),
 			credentials: this.withCredentials ? 'include' : 'same-origin',
 			credentials: this.withCredentials ? 'include' : 'same-origin',
-			// An abort controller could be added within a future PR
+			signal: ( typeof AbortSignal.any === 'function' ) ? AbortSignal.any( [ this._abortController.signal, this.manager.abortController.signal ] ) : this._abortController.signal
 		} );
 		} );
 
 
 		// record states ( avoid data race )
 		// record states ( avoid data race )
@@ -338,6 +346,20 @@ class FileLoader extends Loader {
 
 
 	}
 	}
 
 
+	/**
+	 * Aborts ongoing fetch requests.
+	 *
+	 * @return {FileLoader} A reference to this instance.
+	 */
+	abort() {
+
+		this._abortController.abort();
+		this._abortController = new AbortController();
+
+		return this;
+
+	}
+
 }
 }
 
 
 
 

+ 23 - 0
src/loaders/ImageBitmapLoader.js

@@ -66,6 +66,14 @@ class ImageBitmapLoader extends Loader {
 		 */
 		 */
 		this.options = { premultiplyAlpha: 'none' };
 		this.options = { premultiplyAlpha: 'none' };
 
 
+		/**
+		 * Used for aborting requests.
+		 *
+		 * @private
+		 * @type {AbortController}
+		 */
+		this._abortController = new AbortController();
+
 	}
 	}
 
 
 	/**
 	/**
@@ -154,6 +162,7 @@ class ImageBitmapLoader extends Loader {
 		const fetchOptions = {};
 		const fetchOptions = {};
 		fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include';
 		fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include';
 		fetchOptions.headers = this.requestHeader;
 		fetchOptions.headers = this.requestHeader;
+		fetchOptions.signal = ( typeof AbortSignal.any === 'function' ) ? AbortSignal.any( [ this._abortController.signal, this.manager.abortController.signal ] ) : this._abortController.signal;
 
 
 		const promise = fetch( url, fetchOptions ).then( function ( res ) {
 		const promise = fetch( url, fetchOptions ).then( function ( res ) {
 
 
@@ -191,6 +200,20 @@ class ImageBitmapLoader extends Loader {
 
 
 	}
 	}
 
 
+	/**
+	 * Aborts ongoing fetch requests.
+	 *
+	 * @return {ImageBitmapLoader} A reference to this instance.
+	 */
+	abort() {
+
+		this._abortController.abort();
+		this._abortController = new AbortController();
+
+		return this;
+
+	}
+
 }
 }
 
 
 export { ImageBitmapLoader };
 export { ImageBitmapLoader };

+ 14 - 0
src/loaders/Loader.js

@@ -67,6 +67,7 @@ class Loader {
 	 * This method needs to be implemented by all concrete loaders. It holds the
 	 * This method needs to be implemented by all concrete loaders. It holds the
 	 * logic for loading assets from the backend.
 	 * logic for loading assets from the backend.
 	 *
 	 *
+	 * @abstract
 	 * @param {string} url - The path/URL of the file to be loaded.
 	 * @param {string} url - The path/URL of the file to be loaded.
 	 * @param {Function} onLoad - Executed when the loading process has been finished.
 	 * @param {Function} onLoad - Executed when the loading process has been finished.
 	 * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress.
 	 * @param {onProgressCallback} [onProgress] - Executed while the loading is in progress.
@@ -97,6 +98,7 @@ class Loader {
 	 * This method needs to be implemented by all concrete loaders. It holds the
 	 * This method needs to be implemented by all concrete loaders. It holds the
 	 * logic for parsing the asset into three.js entities.
 	 * logic for parsing the asset into three.js entities.
 	 *
 	 *
+	 * @abstract
 	 * @param {any} data - The data to parse.
 	 * @param {any} data - The data to parse.
 	 */
 	 */
 	parse( /* data */ ) {}
 	parse( /* data */ ) {}
@@ -171,6 +173,18 @@ class Loader {
 
 
 	}
 	}
 
 
+	/**
+	 * This method can be implemented in loaders for aborting ongoing requests.
+	 *
+	 * @abstract
+	 * @return {Loader} A reference to this instance.
+	 */
+	abort() {
+
+		return this;
+
+	}
+
 }
 }
 
 
 /**
 /**

+ 23 - 0
src/loaders/LoadingManager.js

@@ -69,6 +69,13 @@ class LoadingManager {
 		 */
 		 */
 		this.onError = onError;
 		this.onError = onError;
 
 
+		/**
+		 * Used for aborting ongoing requests in loaders using this manager.
+		 *
+		 * @type {AbortController}
+		 */
+		this.abortController = new AbortController();
+
 		/**
 		/**
 		 * This should be called by any loader using the manager when the loader
 		 * This should be called by any loader using the manager when the loader
 		 * starts loading an item.
 		 * starts loading an item.
@@ -269,6 +276,22 @@ class LoadingManager {
 
 
 		};
 		};
 
 
+		/**
+		 * Can be used to abort ongoing loading requests in loaders using this manager.
+		 * The abort only works if the loaders implement {@link Loader#abort} and `AbortSignal.any()`
+		 * is supported in the browser.
+		 *
+		 * @return {LoadingManager} A reference to this loading manager.
+		 */
+		this.abort = function () {
+
+			this.abortController.abort();
+			this.abortController = new AbortController();
+
+			return this;
+
+		};
+
 	}
 	}
 
 
 }
 }

粤ICP备19079148号