next
Version:
The React Framework
97 lines (96 loc) • 4.06 kB
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