mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(core): Split consumerBefore/AfterComputation (#62549)
This makes it possible to batch effects, where we can "reopen" consumers
during initial render and then finalize them after we are finally done
adding all the effects to a batch:
```
function createBatch() {
const effect = // ... create effect node
resetConsumerBeforeComputation(effect);
return effect;
}
// pseudo-code
function appendEffect(effectBatch, updater) {
if (value is a signal) {
const prevConsumer = setActiveConsumer(effectBatch.node);
const output = value();
setActiveConsumer(prevConsumer);
effectBatch.push({ signal, updater });
return output;
}
}
function finalizeBatch(effectBatch) {
if (effectBatch.length > 0) {
finalizeConsumerAfterComputation(effectBatch.node);
}
}
const effectBatch = createBatchEffectNode();
appendEffect(signal1, (newValue) => /* something */);
appendEffect(signal2, (newValue) => /* something different */);
finalizeBatch(effectBatch);
```
PR Close #62549
This commit is contained in:
committed by
Jessica Janiuk
parent
a8fae2aae0
commit
663f48cfc1
@@ -66,6 +66,9 @@ export function createWatch(fn: (onCleanup: WatchCleanupRegisterFn) => void, sch
|
||||
// @public
|
||||
export function defaultEquals<T>(a: T, b: T): boolean;
|
||||
|
||||
// @public
|
||||
export function finalizeConsumerAfterComputation(node: ReactiveNode): void;
|
||||
|
||||
// @public (undocumented)
|
||||
export function getActiveConsumer(): ReactiveNode | null;
|
||||
|
||||
@@ -151,6 +154,9 @@ export interface ReactiveNode {
|
||||
version: Version;
|
||||
}
|
||||
|
||||
// @public
|
||||
export function resetConsumerBeforeComputation(node: ReactiveNode): void;
|
||||
|
||||
// @public (undocumented)
|
||||
export function runEffect(node: BaseEffectNode): void;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ export {
|
||||
consumerDestroy,
|
||||
consumerMarkDirty,
|
||||
consumerPollProducersForChange,
|
||||
finalizeConsumerAfterComputation,
|
||||
getActiveConsumer,
|
||||
isInNotificationPhase,
|
||||
isReactive,
|
||||
@@ -37,6 +38,7 @@ export {
|
||||
producerNotifyConsumers,
|
||||
producerUpdateValueVersion,
|
||||
producerUpdatesAllowed,
|
||||
resetConsumerBeforeComputation,
|
||||
runPostProducerCreatedFn,
|
||||
setActiveConsumer,
|
||||
setPostProducerCreatedFn,
|
||||
|
||||
@@ -359,21 +359,34 @@ export function producerMarkClean(node: ReactiveNode): void {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare this consumer to run a computation in its reactive context.
|
||||
* Prepare this consumer to run a computation in its reactive context and set
|
||||
* it as the active consumer.
|
||||
*
|
||||
* Must be called by subclasses which represent reactive computations, before those computations
|
||||
* begin.
|
||||
*/
|
||||
export function consumerBeforeComputation(node: ReactiveNode | null): ReactiveNode | null {
|
||||
if (node) {
|
||||
node.producersTail = undefined;
|
||||
node.recomputing = true;
|
||||
}
|
||||
if (node) resetConsumerBeforeComputation(node);
|
||||
|
||||
return setActiveConsumer(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize this consumer's state after a reactive computation has run.
|
||||
* Prepare this consumer to run a computation in its reactive context.
|
||||
*
|
||||
* We expose this mainly for code where we manually batch effects into a single
|
||||
* consumer. In those cases we may wish to "reopen" a consumer multiple times
|
||||
* in initial render before finalizing it. Most code should just call
|
||||
* `consumerBeforeComputation` instead of calling this directly.
|
||||
*/
|
||||
export function resetConsumerBeforeComputation(node: ReactiveNode): void {
|
||||
node.producersTail = undefined;
|
||||
node.recomputing = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize this consumer's state and set previous consumer as the active consumer after a
|
||||
* reactive computation has run.
|
||||
*
|
||||
* Must be called by subclasses which represent reactive computations, after those computations
|
||||
* have finished.
|
||||
@@ -384,10 +397,18 @@ export function consumerAfterComputation(
|
||||
): void {
|
||||
setActiveConsumer(prevConsumer);
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
if (node) finalizeConsumerAfterComputation(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize this consumer's state after a reactive computation has run.
|
||||
*
|
||||
* We expose this mainly for code where we manually batch effects into a single
|
||||
* consumer. In those cases we may wish to "reopen" a consumer multiple times
|
||||
* in initial render before finalizing it. Most code should just call
|
||||
* `consumerAfterComputation` instead of calling this directly.
|
||||
*/
|
||||
export function finalizeConsumerAfterComputation(node: ReactiveNode): void {
|
||||
node.recomputing = false;
|
||||
|
||||
// We've finished incrementally rebuilding the producers list, now if there are any producers
|
||||
|
||||
@@ -549,6 +549,7 @@
|
||||
"extractDirectiveDef",
|
||||
"extractStyleParams",
|
||||
"filterNonAnimatableStyles",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAttrIndexInNode",
|
||||
"findDirectiveDefMatches",
|
||||
"flattenGroupPlayers",
|
||||
@@ -850,6 +851,7 @@
|
||||
"replacePostStylesAsPre",
|
||||
"reportUnhandledError",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveDirectives",
|
||||
"resolveElementFromTarget",
|
||||
|
||||
@@ -468,6 +468,7 @@
|
||||
"extractAttrsAndClassesFromSelector",
|
||||
"extractDefListOrFactory",
|
||||
"extractDirectiveDef",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAttrIndexInNode",
|
||||
"findDirectiveDefMatches",
|
||||
"findMatchingDehydratedViewForDeferBlock",
|
||||
@@ -722,6 +723,7 @@
|
||||
"renderView",
|
||||
"reportUnhandledError",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveDirectives",
|
||||
"resolveForwardRef",
|
||||
|
||||
@@ -605,6 +605,7 @@
|
||||
"extractDefListOrFactory",
|
||||
"extractDirectiveDef",
|
||||
"fillProperties",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAttrIndexInNode",
|
||||
"findDirectiveDefMatches",
|
||||
"findExistingListener",
|
||||
@@ -982,6 +983,7 @@
|
||||
"requiredTrueValidator",
|
||||
"requiredValidator",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveComponentResources",
|
||||
"resolveDirectives",
|
||||
|
||||
@@ -604,6 +604,7 @@
|
||||
"extractDefListOrFactory",
|
||||
"extractDirectiveDef",
|
||||
"fillProperties",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAttrIndexInNode",
|
||||
"findDirectiveDefMatches",
|
||||
"findExistingListener",
|
||||
@@ -975,6 +976,7 @@
|
||||
"reportUnhandledError",
|
||||
"requiredValidator",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveComponentResources",
|
||||
"resolveDirectives",
|
||||
|
||||
@@ -485,6 +485,7 @@
|
||||
"extractAttrsAndClassesFromSelector",
|
||||
"extractDefListOrFactory",
|
||||
"extractDirectiveDef",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAndReconcileMatchingDehydratedViewsImpl",
|
||||
"findMatchingDehydratedView",
|
||||
"findMatchingDehydratedViewImpl",
|
||||
@@ -764,6 +765,7 @@
|
||||
"renderView",
|
||||
"reportUnhandledError",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveDirectives",
|
||||
"resolveForwardRef",
|
||||
|
||||
@@ -719,6 +719,7 @@
|
||||
"extractDirectiveDef",
|
||||
"filter",
|
||||
"finalize",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"findAttrIndexInNode",
|
||||
"findDirectiveDefMatches",
|
||||
"findExistingListener",
|
||||
@@ -1116,6 +1117,7 @@
|
||||
"replaceSegment",
|
||||
"reportUnhandledError",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveData",
|
||||
"resolveDirectives",
|
||||
|
||||
@@ -399,6 +399,7 @@
|
||||
"extractAttrsAndClassesFromSelector",
|
||||
"extractDefListOrFactory",
|
||||
"extractDirectiveDef",
|
||||
"finalizeConsumerAfterComputation",
|
||||
"forEachSingleProvider",
|
||||
"forkInnerZoneWithAngularBehavior",
|
||||
"formatErrorMessage",
|
||||
@@ -616,6 +617,7 @@
|
||||
"renderView",
|
||||
"reportUnhandledError",
|
||||
"requiresRefreshOrTraversal",
|
||||
"resetConsumerBeforeComputation",
|
||||
"resetPreOrderHookFlags",
|
||||
"resolveDirectives",
|
||||
"resolveForwardRef",
|
||||
|
||||
Reference in New Issue
Block a user