@@ -21,6 +21,7 @@ import type StyleLayerIndex from '../style/style_layer_index';
2121import type { LoadVectorDataCallback } from './vector_tile_worker_source' ;
2222import type { RequestParameters , ResponseCallback } from '../util/ajax' ;
2323import type { Callback } from '../types/callback' ;
24+ import type { Cancelable } from '../types/cancelable' ;
2425
2526export type LoadGeoJSONParameters = {
2627 request ?: RequestParameters ;
@@ -33,7 +34,7 @@ export type LoadGeoJSONParameters = {
3334 filter ?: Array < unknown > ;
3435} ;
3536
36- export type LoadGeoJSON = ( params : LoadGeoJSONParameters , callback : ResponseCallback < any > ) => void ;
37+ export type LoadGeoJSON = ( params : LoadGeoJSONParameters , callback : ResponseCallback < any > ) => Cancelable ;
3738
3839export interface GeoJSONIndex {
3940 getTile ( z : number , x : number , y : number ) : any ;
@@ -72,10 +73,6 @@ function loadGeoJSONTile(params: WorkerTileParameters, callback: LoadVectorDataC
7273 } ) ;
7374}
7475
75- export type SourceState = // Source empty or data loaded
76- 'Idle' | // Data finished loading, but discard 'loadData' messages until receiving 'coalesced'
77- 'Coalescing' | 'NeedsLoadData' ; // 'loadData' received while coalescing, trigger one more 'loadData' on receiving 'coalesced'
78-
7976/**
8077 * The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
8178 * This class is designed to be easily reused to support custom source types
@@ -87,12 +84,11 @@ export type SourceState = // Source empty or data loaded
8784 * @private
8885 */
8986class GeoJSONWorkerSource extends VectorTileWorkerSource {
90- _state : SourceState ;
9187 _pendingCallback : Callback < {
9288 resourceTiming ?: { [ _ : string ] : Array < PerformanceResourceTiming > } ;
9389 abandoned ?: boolean ;
9490 } > ;
95- _pendingLoadDataParams : LoadGeoJSONParameters ;
91+ _pendingRequest : Cancelable ;
9692 _geoJSONIndex : GeoJSONIndex ;
9793
9894 /**
@@ -117,9 +113,8 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
117113 * expecting `callback(error, data)` to be called with either an error or a
118114 * parsed GeoJSON object.
119115 *
120- * When `loadData` requests come in faster than they can be processed,
121- * they are coalesced into a single request using the latest data.
122- * See {@link GeoJSONWorkerSource#coalesce}
116+ * When a `loadData` request comes in while a previous one is being processed,
117+ * the previous one is aborted.
123118 *
124119 * @param params
125120 * @param callback
@@ -129,40 +124,20 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
129124 resourceTiming ?: { [ _ : string ] : Array < PerformanceResourceTiming > } ;
130125 abandoned ?: boolean ;
131126 } > ) {
127+ this . _pendingRequest ?. cancel ( ) ;
132128 if ( this . _pendingCallback ) {
133129 // Tell the foreground the previous call has been abandoned
134130 this . _pendingCallback ( null , { abandoned : true } ) ;
135131 }
136- this . _pendingCallback = callback ;
137- this . _pendingLoadDataParams = params ;
138-
139- if ( this . _state &&
140- this . _state !== 'Idle' ) {
141- this . _state = 'NeedsLoadData' ;
142- } else {
143- this . _state = 'Coalescing' ;
144- this . _loadData ( ) ;
145- }
146- }
147-
148- /**
149- * Internal implementation: called directly by `loadData`
150- * or by `coalesce` using stored parameters.
151- */
152- _loadData ( ) {
153- if ( ! this . _pendingCallback || ! this . _pendingLoadDataParams ) {
154- assert ( false ) ;
155- return ;
156- }
157- const callback = this . _pendingCallback ;
158- const params = this . _pendingLoadDataParams ;
159- delete this . _pendingCallback ;
160- delete this . _pendingLoadDataParams ;
161132
162133 const perf = ( params && params . request && params . request . collectResourceTiming ) ?
163134 new RequestPerformance ( params . request ) : false ;
164135
165- this . loadGeoJSON ( params , ( err ?: Error | null , data ?: any | null ) => {
136+ this . _pendingCallback = callback ;
137+ this . _pendingRequest = this . loadGeoJSON ( params , ( err ?: Error | null , data ?: any | null ) => {
138+ delete this . _pendingCallback ;
139+ delete this . _pendingRequest ;
140+
166141 if ( err || ! data ) {
167142 return callback ( err ) ;
168143 } else if ( typeof data !== 'object' ) {
@@ -204,35 +179,6 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
204179 } ) ;
205180 }
206181
207- /**
208- * While processing `loadData`, we coalesce all further
209- * `loadData` messages into a single call to _loadData
210- * that will happen once we've finished processing the
211- * first message. {@link GeoJSONSource#_updateWorkerData}
212- * is responsible for sending us the `coalesce` message
213- * at the time it receives a response from `loadData`
214- *
215- * State: Idle
216- * ↑ |
217- * 'coalesce' 'loadData'
218- * | (triggers load)
219- * | ↓
220- * State: Coalescing
221- * ↑ |
222- * (triggers load) |
223- * 'coalesce' 'loadData'
224- * | ↓
225- * State: NeedsLoadData
226- */
227- coalesce ( ) {
228- if ( this . _state === 'Coalescing' ) {
229- this . _state = 'Idle' ;
230- } else if ( this . _state === 'NeedsLoadData' ) {
231- this . _state = 'Coalescing' ;
232- this . _loadData ( ) ;
233- }
234- }
235-
236182 /**
237183 * Implements {@link WorkerSource#reloadTile}.
238184 *
@@ -264,24 +210,27 @@ class GeoJSONWorkerSource extends VectorTileWorkerSource {
264210 * @param params
265211 * @param [params.url] A URL to the remote GeoJSON data.
266212 * @param [params.data] Literal GeoJSON data. Must be provided if `params.url` is not.
213+ * @returns {Cancelable } A Cancelable object.
267214 * @private
268215 */
269- loadGeoJSON ( params : LoadGeoJSONParameters , callback : ResponseCallback < any > ) {
216+ loadGeoJSON ( params : LoadGeoJSONParameters , callback : ResponseCallback < any > ) : Cancelable {
270217 // Because of same origin issues, urls must either include an explicit
271218 // origin or absolute path.
272219 // ie: /foo/bar.json or http://example.com/bar.json
273220 // but not ../foo/bar.json
274221 if ( params . request ) {
275- getJSON ( params . request , callback ) ;
222+ return getJSON ( params . request , callback ) ;
276223 } else if ( typeof params . data === 'string' ) {
277224 try {
278- return callback ( null , JSON . parse ( params . data ) ) ;
225+ callback ( null , JSON . parse ( params . data ) ) ;
279226 } catch ( e ) {
280- return callback ( new Error ( `Input data given to '${ params . source } ' is not a valid GeoJSON object.` ) ) ;
227+ callback ( new Error ( `Input data given to '${ params . source } ' is not a valid GeoJSON object.` ) ) ;
281228 }
282229 } else {
283- return callback ( new Error ( `Input data given to '${ params . source } ' is not a valid GeoJSON object.` ) ) ;
230+ callback ( new Error ( `Input data given to '${ params . source } ' is not a valid GeoJSON object.` ) ) ;
284231 }
232+
233+ return { cancel : ( ) => { } } ;
285234 }
286235
287236 removeSource ( params : {
0 commit comments