diff --git a/packages/scheduler/src/SchedulerFeatureFlags.js b/packages/scheduler/src/SchedulerFeatureFlags.js index b8c54a462e3a8..182093a93c85c 100644 --- a/packages/scheduler/src/SchedulerFeatureFlags.js +++ b/packages/scheduler/src/SchedulerFeatureFlags.js @@ -14,4 +14,3 @@ export const enableIsInputPendingContinuous = false; export const frameYieldMs = 5; export const continuousYieldMs = 50; export const maxYieldMs = 300; -export const enableSchedulerYield = false; diff --git a/packages/scheduler/src/__tests__/SchedulerPostTask-test.js b/packages/scheduler/src/__tests__/SchedulerPostTask-test.js index 9aafbd98e875c..d76ca570c2f31 100644 --- a/packages/scheduler/src/__tests__/SchedulerPostTask-test.js +++ b/packages/scheduler/src/__tests__/SchedulerPostTask-test.js @@ -96,9 +96,7 @@ describe('SchedulerPostTask', () => { scheduler.yield = function ({priority, signal}) { const id = idCounter++; - log( - `Post Task ${id} [${priority === undefined ? '' : priority}]`, - ); + log(`Yield ${id} [${priority === undefined ? '' : priority}]`); const controller = signal._controller; let callback; @@ -196,7 +194,7 @@ describe('SchedulerPostTask', () => { 'Task 0 Fired', 'A', 'Yield at 5ms', - 'Post Task 1 [user-visible]', + 'Yield 1 [user-visible]', ]); runtime.flushTasks(); @@ -339,7 +337,7 @@ describe('SchedulerPostTask', () => { // The continuation should be scheduled in a separate macrotask even // though there's time remaining. - 'Post Task 1 [user-visible]', + 'Yield 1 [user-visible]', ]); // No time has elapsed @@ -348,4 +346,67 @@ describe('SchedulerPostTask', () => { runtime.flushTasks(); runtime.assertLog(['Task 1 Fired', 'Continuation Task']); }); + + describe('falls back to postTask for scheduling continuations when scheduler.yield is not available', () => { + beforeEach(() => { + delete global.scheduler.yield; + }); + + it('task with continuation', () => { + scheduleCallback(NormalPriority, () => { + runtime.log('A'); + while (!Scheduler.unstable_shouldYield()) { + runtime.advanceTime(1); + } + runtime.log(`Yield at ${performance.now()}ms`); + return () => { + runtime.log('Continuation'); + }; + }); + runtime.assertLog(['Post Task 0 [user-visible]']); + + runtime.flushTasks(); + runtime.assertLog([ + 'Task 0 Fired', + 'A', + 'Yield at 5ms', + 'Post Task 1 [user-visible]', + ]); + + runtime.flushTasks(); + runtime.assertLog(['Task 1 Fired', 'Continuation']); + }); + + it('yielding continues in a new task regardless of how much time is remaining', () => { + scheduleCallback(NormalPriority, () => { + runtime.log('Original Task'); + runtime.log('shouldYield: ' + shouldYield()); + runtime.log('Return a continuation'); + return () => { + runtime.log('Continuation Task'); + }; + }); + runtime.assertLog(['Post Task 0 [user-visible]']); + + runtime.flushTasks(); + runtime.assertLog([ + 'Task 0 Fired', + 'Original Task', + // Immediately before returning a continuation, `shouldYield` returns + // false, which means there must be time remaining in the frame. + 'shouldYield: false', + 'Return a continuation', + + // The continuation should be scheduled in a separate macrotask even + // though there's time remaining. + 'Post Task 1 [user-visible]', + ]); + + // No time has elapsed + expect(performance.now()).toBe(0); + + runtime.flushTasks(); + runtime.assertLog(['Task 1 Fired', 'Continuation Task']); + }); + }); }); diff --git a/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js b/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js index 47231da8e0ff9..8232400b84d32 100644 --- a/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js +++ b/packages/scheduler/src/forks/SchedulerFeatureFlags.www-dynamic.js @@ -12,4 +12,3 @@ // with the __VARIANT__ set to `true`, and once set to `false`. export const enableProfiling = __VARIANT__; -export const enableSchedulerYield = __VARIANT__; diff --git a/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js b/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js index 86766e41d4fa9..4ad93cb70e594 100644 --- a/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js +++ b/packages/scheduler/src/forks/SchedulerFeatureFlags.www.js @@ -7,17 +7,13 @@ * @flow */ -const { - enableProfiling: enableProfilingFeatureFlag, - enableSchedulerYield: enableSchedulerYieldFeatureFlag, -} = +const {enableProfiling: enableProfilingFeatureFlag} = // $FlowFixMe[cannot-resolve-module] require('SchedulerFeatureFlags'); export const enableSchedulerDebugging = true; export const enableProfiling: boolean = __PROFILE__ && enableProfilingFeatureFlag; -export const enableSchedulerYield = enableSchedulerYieldFeatureFlag; export const enableIsInputPending = true; export const enableIsInputPendingContinuous = true; export const frameYieldMs = 5; diff --git a/packages/scheduler/src/forks/SchedulerPostTask.js b/packages/scheduler/src/forks/SchedulerPostTask.js index f2a25cb92c263..5af147117ef56 100644 --- a/packages/scheduler/src/forks/SchedulerPostTask.js +++ b/packages/scheduler/src/forks/SchedulerPostTask.js @@ -9,8 +9,6 @@ import type {PriorityLevel} from '../SchedulerPriorities'; -import {enableSchedulerYield} from '../SchedulerFeatureFlags'; - declare class TaskController { constructor(priority?: string): TaskController; signal: mixed; @@ -149,7 +147,7 @@ function runTask( continuation, ); - if (enableSchedulerYield && scheduler.yield !== undefined) { + if (scheduler.yield !== undefined) { scheduler .yield(continuationOptions) .then(nextTask)