1
1
/* global fetch:true, Promise:true, document:true */
2
2
import {
3
+ adjust ,
4
+ any ,
3
5
concat ,
4
6
contains ,
7
+ findIndex ,
8
+ findLastIndex ,
5
9
has ,
6
10
intersection ,
7
11
isEmpty ,
8
12
keys ,
9
13
lensPath ,
14
+ lensProp ,
10
15
pluck ,
11
- reject ,
16
+ propEq ,
17
+ set ,
12
18
slice ,
13
19
sort ,
14
20
type ,
15
- union ,
16
21
view
17
22
} from 'ramda' ;
18
23
import { createAction } from 'redux-actions' ;
19
24
import { crawlLayout , hasId } from '../reducers/utils' ;
20
25
import { APP_STATES } from '../reducers/constants' ;
21
26
import { ACTIONS } from './constants' ;
22
27
import cookie from 'cookie' ;
23
- import { urlBase } from '../utils' ;
28
+ import { uid , urlBase } from '../utils' ;
24
29
25
30
export const updateProps = createAction ( ACTIONS ( 'ON_PROP_CHANGE' ) ) ;
26
31
export const setRequestQueue = createAction ( ACTIONS ( 'SET_REQUEST_QUEUE' ) ) ;
@@ -253,8 +258,9 @@ export function notifyObservers(payload) {
253
258
* the change for Child. if this update has already been queued up,
254
259
* then skip the update for the other component
255
260
*/
256
- const controllersInExistingQueue = intersection (
257
- requestQueue , controllers
261
+ const controllerIsInExistingQueue = any ( r =>
262
+ contains ( r . controllerId , controllers ) && r . status === 'loading' ,
263
+ requestQueue
258
264
) ;
259
265
260
266
/*
@@ -267,7 +273,7 @@ export function notifyObservers(payload) {
267
273
if (
268
274
( controllersInFutureQueue . length === 0 ) &&
269
275
( has ( outputComponentId , getState ( ) . paths ) ) &&
270
- ( controllersInExistingQueue . length === 0 )
276
+ ! controllerIsInExistingQueue
271
277
) {
272
278
queuedObservers . push ( outputIdAndProp )
273
279
}
@@ -278,7 +284,15 @@ export function notifyObservers(payload) {
278
284
* updated in a queue. not all of these requests will be fired in this
279
285
* action
280
286
*/
281
- dispatch ( setRequestQueue ( union ( queuedObservers , requestQueue ) ) ) ;
287
+ const newRequestQueue = queuedObservers . map (
288
+ i => ( { controllerId : i , status : 'loading' , uid : uid ( ) } )
289
+ )
290
+ dispatch ( setRequestQueue (
291
+ concat (
292
+ requestQueue ,
293
+ newRequestQueue
294
+ )
295
+ ) ) ;
282
296
283
297
const promises = [ ] ;
284
298
for ( let i = 0 ; i < queuedObservers . length ; i ++ ) {
@@ -356,13 +370,33 @@ export function notifyObservers(payload) {
356
370
payload : { status : res . status }
357
371
} ) ;
358
372
359
- // clear this item from the request queue
360
- dispatch ( setRequestQueue (
361
- reject (
362
- id => id === outputIdAndProp ,
363
- getState ( ) . requestQueue
364
- )
365
- ) ) ;
373
+ // update the status of this request
374
+ const postRequestQueue = getState ( ) . requestQueue ;
375
+ const requestUid = newRequestQueue [ i ] . uid ;
376
+ const thisRequestIndex = findIndex (
377
+ propEq ( 'uid' , requestUid ) ,
378
+ postRequestQueue
379
+ ) ;
380
+ const updatedQueue = adjust (
381
+ set ( lensProp ( 'status' ) , res . status ) ,
382
+ thisRequestIndex ,
383
+ postRequestQueue
384
+ ) ;
385
+ dispatch ( setRequestQueue ( updatedQueue ) ) ;
386
+
387
+ /*
388
+ * Check to see if another request has already come back
389
+ * _after_ this one.
390
+ * If so, ignore this request.
391
+ */
392
+ const latestRequestIndex = findLastIndex (
393
+ propEq ( 'controllerId' , newRequestQueue [ i ] . controllerId ) ,
394
+ updatedQueue
395
+ ) ;
396
+ if ( latestRequestIndex > thisRequestIndex &&
397
+ updatedQueue [ latestRequestIndex ] . status === 200 ) {
398
+ return ;
399
+ }
366
400
367
401
return res . json ( ) . then ( function handleJson ( data ) {
368
402
0 commit comments