@@ -399,33 +399,10 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
399
399
// no longer blocked, return the time at which it completed so that we
400
400
// can commit it.
401
401
if ( isRootBlocked ( root , completedAt ) ) {
402
- // Process pending completion callbacks so that they are called at
403
- // the end of the current batch.
404
- const completionCallbacks = root . completionCallbacks ;
405
- if ( completionCallbacks !== null ) {
406
- processUpdateQueue (
407
- completionCallbacks ,
408
- null ,
409
- null ,
410
- null ,
411
- completedAt ,
412
- ) ;
413
- const callbackList = completionCallbacks . callbackList ;
414
- if ( callbackList !== null ) {
415
- // Add new callbacks to list of completion callbacks
416
- if ( rootCompletionCallbackList === null ) {
417
- rootCompletionCallbackList = callbackList ;
418
- } else {
419
- for ( let i = 0 ; i < callbackList . length ; i ++ ) {
420
- rootCompletionCallbackList . push ( callbackList [ i ] ) ;
421
- }
422
- }
423
- completionCallbacks . callbackList = null ;
424
- if ( completionCallbacks . first === null ) {
425
- root . completionCallbacks = null ;
426
- }
427
- }
428
- }
402
+ // We usually process completion callbacks right after a root is
403
+ // completed. But this root already completed, and it's possible that
404
+ // we received new completion callbacks since then.
405
+ processCompletionCallbacks ( root , completedAt ) ;
429
406
return Done ;
430
407
}
431
408
@@ -435,6 +412,33 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
435
412
return expirationTime ;
436
413
}
437
414
415
+ function processCompletionCallbacks (
416
+ root : FiberRoot ,
417
+ completedAt : ExpirationTime ,
418
+ ) {
419
+ // Process pending completion callbacks so that they are called at
420
+ // the end of the current batch.
421
+ const completionCallbacks = root . completionCallbacks ;
422
+ if ( completionCallbacks !== null ) {
423
+ processUpdateQueue ( completionCallbacks , null , null , null , completedAt ) ;
424
+ const callbackList = completionCallbacks . callbackList ;
425
+ if ( callbackList !== null ) {
426
+ // Add new callbacks to list of completion callbacks
427
+ if ( rootCompletionCallbackList === null ) {
428
+ rootCompletionCallbackList = callbackList ;
429
+ } else {
430
+ for ( let i = 0 ; i < callbackList . length ; i ++ ) {
431
+ rootCompletionCallbackList . push ( callbackList [ i ] ) ;
432
+ }
433
+ }
434
+ completionCallbacks . callbackList = null ;
435
+ if ( completionCallbacks . first === null ) {
436
+ root . completionCallbacks = null ;
437
+ }
438
+ }
439
+ }
440
+ }
441
+
438
442
function commitAllHostEffects ( ) {
439
443
while ( nextEffect !== null ) {
440
444
if ( __DEV__ ) {
@@ -820,6 +824,7 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
820
824
// The root is not blocked, so we can commit it now.
821
825
pendingCommit = workInProgress ;
822
826
}
827
+ processCompletionCallbacks ( root , nextRenderExpirationTime ) ;
823
828
return null ;
824
829
}
825
830
}
@@ -1602,12 +1607,9 @@ module.exports = function<T, P, I, TI, PI, C, CX, PL>(
1602
1607
}
1603
1608
break ;
1604
1609
case TaskPriority :
1605
- invariant (
1606
- isBatchingUpdates ,
1607
- 'Task updates can only be scheduled as a nested update or ' +
1608
- 'inside batchedUpdates. This error is likely caused by a ' +
1609
- 'bug in React. Please file an issue.' ,
1610
- ) ;
1610
+ if ( ! isPerformingWork && ! isBatchingUpdates ) {
1611
+ performWork ( TaskPriority , null ) ;
1612
+ }
1611
1613
break ;
1612
1614
default :
1613
1615
// This update is async. Schedule a callback.
0 commit comments