| import { InvariantError } from '../../shared/lib/invariant-error' |
| import { createAtomicTimerGroup } from './app-render-scheduling' |
| import { |
| DANGEROUSLY_runPendingImmediatesAfterCurrentTask, |
| expectNoPendingImmediates, |
| } from '../node-environment-extensions/fast-set-immediate.external' |
|
|
| |
| |
| |
| |
| export function scheduleInSequentialTasks<R>( |
| render: () => R | Promise<R>, |
| followup: () => void |
| ): Promise<R> { |
| if (process.env.NEXT_RUNTIME === 'edge') { |
| throw new InvariantError( |
| '`scheduleInSequentialTasks` should not be called in edge runtime.' |
| ) |
| } else { |
| return new Promise((resolve, reject) => { |
| const scheduleTimeout = createAtomicTimerGroup() |
|
|
| let pendingResult: R | Promise<R> |
| scheduleTimeout(() => { |
| try { |
| DANGEROUSLY_runPendingImmediatesAfterCurrentTask() |
| pendingResult = render() |
| } catch (err) { |
| reject(err) |
| } |
| }) |
|
|
| scheduleTimeout(() => { |
| try { |
| expectNoPendingImmediates() |
| followup() |
| resolve(pendingResult) |
| } catch (err) { |
| reject(err) |
| } |
| }) |
| }) |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| export function pipelineInSequentialTasks<A, B, C>( |
| one: () => A, |
| two: (a: A) => B, |
| three: (b: B) => C |
| ): Promise<C> { |
| if (process.env.NEXT_RUNTIME === 'edge') { |
| throw new InvariantError( |
| '`pipelineInSequentialTasks` should not be called in edge runtime.' |
| ) |
| } else { |
| return new Promise((resolve, reject) => { |
| const scheduleTimeout = createAtomicTimerGroup() |
|
|
| let oneResult: A |
| scheduleTimeout(() => { |
| try { |
| DANGEROUSLY_runPendingImmediatesAfterCurrentTask() |
| oneResult = one() |
| } catch (err) { |
| clearTimeout(twoId) |
| clearTimeout(threeId) |
| clearTimeout(fourId) |
| reject(err) |
| } |
| }) |
|
|
| let twoResult: B |
| const twoId = scheduleTimeout(() => { |
| |
| |
| try { |
| DANGEROUSLY_runPendingImmediatesAfterCurrentTask() |
| twoResult = two(oneResult!) |
| } catch (err) { |
| clearTimeout(threeId) |
| clearTimeout(fourId) |
| reject(err) |
| } |
| }) |
|
|
| let threeResult: C |
| const threeId = scheduleTimeout(() => { |
| |
| |
| try { |
| expectNoPendingImmediates() |
| threeResult = three(twoResult!) |
| } catch (err) { |
| clearTimeout(fourId) |
| reject(err) |
| } |
| }) |
|
|
| |
| const fourId = scheduleTimeout(() => { |
| resolve(threeResult) |
| }) |
| }) |
| } |
| } |
|
|