97 lines
4.0 KiB
JavaScript
97 lines
4.0 KiB
JavaScript
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';
|
|
/**
|
|
* This is a utility function to make scheduling sequential tasks that run back to back easier.
|
|
* We schedule on the same queue (setTimeout) at the same time to ensure no other events can sneak in between.
|
|
*/ export function scheduleInSequentialTasks(render, followup) {
|
|
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
throw Object.defineProperty(new InvariantError('`scheduleInSequentialTasks` should not be called in edge runtime.'), "__NEXT_ERROR_CODE", {
|
|
value: "E591",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
} else {
|
|
return new Promise((resolve, reject)=>{
|
|
const scheduleTimeout = createAtomicTimerGroup();
|
|
let pendingResult;
|
|
scheduleTimeout(()=>{
|
|
try {
|
|
DANGEROUSLY_runPendingImmediatesAfterCurrentTask();
|
|
pendingResult = render();
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
scheduleTimeout(()=>{
|
|
try {
|
|
expectNoPendingImmediates();
|
|
followup();
|
|
resolve(pendingResult);
|
|
} catch (err) {
|
|
reject(err);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
/**
|
|
* This is a utility function to make scheduling sequential tasks that run back to back easier.
|
|
* We schedule on the same queue (setTimeout) at the same time to ensure no other events can sneak in between.
|
|
* The function that runs in the second task gets access to the first tasks's result.
|
|
*/ export function pipelineInSequentialTasks(one, two, three) {
|
|
if (process.env.NEXT_RUNTIME === 'edge') {
|
|
throw Object.defineProperty(new InvariantError('`pipelineInSequentialTasks` should not be called in edge runtime.'), "__NEXT_ERROR_CODE", {
|
|
value: "E875",
|
|
enumerable: false,
|
|
configurable: true
|
|
});
|
|
} else {
|
|
return new Promise((resolve, reject)=>{
|
|
const scheduleTimeout = createAtomicTimerGroup();
|
|
let oneResult;
|
|
scheduleTimeout(()=>{
|
|
try {
|
|
DANGEROUSLY_runPendingImmediatesAfterCurrentTask();
|
|
oneResult = one();
|
|
} catch (err) {
|
|
clearTimeout(twoId);
|
|
clearTimeout(threeId);
|
|
clearTimeout(fourId);
|
|
reject(err);
|
|
}
|
|
});
|
|
let twoResult;
|
|
const twoId = scheduleTimeout(()=>{
|
|
// if `one` threw, then this timeout would've been cleared,
|
|
// so if we got here, we're guaranteed to have a value.
|
|
try {
|
|
DANGEROUSLY_runPendingImmediatesAfterCurrentTask();
|
|
twoResult = two(oneResult);
|
|
} catch (err) {
|
|
clearTimeout(threeId);
|
|
clearTimeout(fourId);
|
|
reject(err);
|
|
}
|
|
});
|
|
let threeResult;
|
|
const threeId = scheduleTimeout(()=>{
|
|
// if `two` threw, then this timeout would've been cleared,
|
|
// so if we got here, we're guaranteed to have a value.
|
|
try {
|
|
expectNoPendingImmediates();
|
|
threeResult = three(twoResult);
|
|
} catch (err) {
|
|
clearTimeout(fourId);
|
|
reject(err);
|
|
}
|
|
});
|
|
// We wait a task before resolving/rejecting
|
|
const fourId = scheduleTimeout(()=>{
|
|
resolve(threeResult);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
//# sourceMappingURL=app-render-render-utils.js.map
|