diff --git a/src/loaders/AnimationLoader.js b/src/loaders/AnimationLoader.js index 661dab954034cd..e814002990ef49 100644 --- a/src/loaders/AnimationLoader.js +++ b/src/loaders/AnimationLoader.js @@ -18,6 +18,8 @@ class AnimationLoader extends Loader { loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); loader.setWithCredentials( this.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( text ) { try { diff --git a/src/loaders/AudioLoader.js b/src/loaders/AudioLoader.js index 857394e4812f71..0d6a26dc0bc5d4 100644 --- a/src/loaders/AudioLoader.js +++ b/src/loaders/AudioLoader.js @@ -19,6 +19,8 @@ class AudioLoader extends Loader { loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); loader.setWithCredentials( this.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( buffer ) { try { diff --git a/src/loaders/BufferGeometryLoader.js b/src/loaders/BufferGeometryLoader.js index 5e9b19dfacfa48..1f112e800f5b02 100644 --- a/src/loaders/BufferGeometryLoader.js +++ b/src/loaders/BufferGeometryLoader.js @@ -26,6 +26,8 @@ class BufferGeometryLoader extends Loader { loader.setPath( scope.path ); loader.setRequestHeader( scope.requestHeader ); loader.setWithCredentials( scope.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( text ) { try { diff --git a/src/loaders/CompressedTextureLoader.js b/src/loaders/CompressedTextureLoader.js index 02ef233412d314..05aa3135e7a032 100644 --- a/src/loaders/CompressedTextureLoader.js +++ b/src/loaders/CompressedTextureLoader.js @@ -30,6 +30,7 @@ class CompressedTextureLoader extends Loader { loader.setResponseType( 'arraybuffer' ); loader.setRequestHeader( this.requestHeader ); loader.setWithCredentials( scope.withCredentials ); + loader.setAbortSignal( this.abortSignal ); let loaded = 0; diff --git a/src/loaders/CubeTextureLoader.js b/src/loaders/CubeTextureLoader.js index 2e784a221e8d27..a1daa480a0ab20 100644 --- a/src/loaders/CubeTextureLoader.js +++ b/src/loaders/CubeTextureLoader.js @@ -17,6 +17,7 @@ class CubeTextureLoader extends Loader { const loader = new ImageLoader( this.manager ); loader.setCrossOrigin( this.crossOrigin ); loader.setPath( this.path ); + loader.setAbortSignal( this.abortSignal ); let loaded = 0; diff --git a/src/loaders/DataTextureLoader.js b/src/loaders/DataTextureLoader.js index e584dbb9412ac8..9a6bac5f8bb0dc 100644 --- a/src/loaders/DataTextureLoader.js +++ b/src/loaders/DataTextureLoader.js @@ -28,6 +28,8 @@ class DataTextureLoader extends Loader { loader.setRequestHeader( this.requestHeader ); loader.setPath( this.path ); loader.setWithCredentials( scope.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( buffer ) { const texData = scope.parse( buffer ); diff --git a/src/loaders/FileLoader.js b/src/loaders/FileLoader.js index b42e55bc752ebf..bc6b6e25a77d13 100644 --- a/src/loaders/FileLoader.js +++ b/src/loaders/FileLoader.js @@ -66,11 +66,12 @@ class FileLoader extends Loader { const req = new Request( url, { headers: new Headers( this.requestHeader ), credentials: this.withCredentials ? 'include' : 'same-origin', - // An abort controller could be added within a future PR } ); // start the fetch - fetch( req ) + fetch( req, { + signal: this.abortSignal, + } ) .then( response => { if ( response.status === 200 || response.status === 0 ) { diff --git a/src/loaders/ImageBitmapLoader.js b/src/loaders/ImageBitmapLoader.js index 2a9d15a3742840..ab7e58ec8ae2a8 100644 --- a/src/loaders/ImageBitmapLoader.js +++ b/src/loaders/ImageBitmapLoader.js @@ -59,11 +59,14 @@ class ImageBitmapLoader extends Loader { } - const fetchOptions = {}; - fetchOptions.credentials = ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include'; - fetchOptions.headers = this.requestHeader; + const req = new Request( url, { + credentials: ( this.crossOrigin === 'anonymous' ) ? 'same-origin' : 'include', + headers: new Headers( this.requestHeader ), + } ); - fetch( url, fetchOptions ).then( function ( res ) { + fetch( req, { + signal: this.abortSignal, + } ).then( function ( res ) { return res.blob(); diff --git a/src/loaders/ImageLoader.js b/src/loaders/ImageLoader.js index 48a98c0f61e17b..baf551bd08b0c3 100644 --- a/src/loaders/ImageLoader.js +++ b/src/loaders/ImageLoader.js @@ -61,16 +61,34 @@ class ImageLoader extends Loader { } + function onAbortSignal() { + + image.src = null; + + } + function removeEventListeners() { image.removeEventListener( 'load', onImageLoad, false ); image.removeEventListener( 'error', onImageError, false ); + if ( this.abortSignal ) { + + this.abortSignal.removeEventListener( 'abort', onAbortSignal, false ); + + } + } image.addEventListener( 'load', onImageLoad, false ); image.addEventListener( 'error', onImageError, false ); + if ( this.abortSignal ) { + + this.abortSignal.addEventListener( 'abort', onAbortSignal, false ); + + } + if ( url.substr( 0, 5 ) !== 'data:' ) { if ( this.crossOrigin !== undefined ) image.crossOrigin = this.crossOrigin; diff --git a/src/loaders/Loader.js b/src/loaders/Loader.js index 3d161b5d6f62b5..62740e39210cfc 100644 --- a/src/loaders/Loader.js +++ b/src/loaders/Loader.js @@ -11,6 +11,7 @@ class Loader { this.path = ''; this.resourcePath = ''; this.requestHeader = {}; + this.abortSignal = null; } @@ -65,6 +66,13 @@ class Loader { } + setAbortSignal( abortSignal ) { + + this.abortSignal = abortSignal; + return this; + + } + } export { Loader }; diff --git a/src/loaders/MaterialLoader.js b/src/loaders/MaterialLoader.js index 2af3967528bfc6..4d6f34e3e54b13 100644 --- a/src/loaders/MaterialLoader.js +++ b/src/loaders/MaterialLoader.js @@ -25,6 +25,8 @@ class MaterialLoader extends Loader { loader.setPath( scope.path ); loader.setRequestHeader( scope.requestHeader ); loader.setWithCredentials( scope.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( text ) { try { diff --git a/src/loaders/ObjectLoader.js b/src/loaders/ObjectLoader.js index f263ad885f10b1..9dfbc18e574e52 100644 --- a/src/loaders/ObjectLoader.js +++ b/src/loaders/ObjectLoader.js @@ -79,6 +79,8 @@ class ObjectLoader extends Loader { loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); loader.setWithCredentials( this.withCredentials ); + loader.setAbortSignal( this.abortSignal ); + loader.load( url, function ( text ) { let json = null; @@ -123,6 +125,7 @@ class ObjectLoader extends Loader { loader.setPath( this.path ); loader.setRequestHeader( this.requestHeader ); loader.setWithCredentials( this.withCredentials ); + loader.setAbortSignal( this.abortSignal ); const text = await loader.loadAsync( url, onProgress ); @@ -451,6 +454,7 @@ class ObjectLoader extends Loader { loader = new ImageLoader( manager ); loader.setCrossOrigin( this.crossOrigin ); + loader.setAbortSignal( this.abortSignal ); for ( let i = 0, il = json.length; i < il; i ++ ) { @@ -550,6 +554,7 @@ class ObjectLoader extends Loader { loader = new ImageLoader( this.manager ); loader.setCrossOrigin( this.crossOrigin ); + loader.setAbortSignal( this.abortSignal ); for ( let i = 0, il = json.length; i < il; i ++ ) { diff --git a/src/loaders/TextureLoader.js b/src/loaders/TextureLoader.js index 4adc1ec8fa4aed..6ceccdfb88db21 100644 --- a/src/loaders/TextureLoader.js +++ b/src/loaders/TextureLoader.js @@ -17,6 +17,7 @@ class TextureLoader extends Loader { const loader = new ImageLoader( this.manager ); loader.setCrossOrigin( this.crossOrigin ); loader.setPath( this.path ); + loader.setAbortSignal( this.abortSignal ); loader.load( url, function ( image ) {