| | 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) |
| | }) |
| | }) |
| | } |
| | } |
| |
|