[Typescript] Use Bitwise Flags

Zhentiw發表於2024-11-19
export enum EffectFlags {
  /**
   * ReactiveEffect only
   */
  ACTIVE = 1 << 0,
  RUNNING = 1 << 1,
  TRACKING = 1 << 2,
  NOTIFIED = 1 << 3,
  DIRTY = 1 << 4,
  ALLOW_RECURSE = 1 << 5,
  PAUSED = 1 << 6,
}

What is 1 << N?

1 << N is a bitwise left shift operation, where the binary representation of 1 is shifted N positions to the left. This is used to create flags that represent powers of 2 (1, 2, 4, 8, etc.). These values can be combined using bitwise operations (e.g., | for combining flags or & for checking flags).

For example:

  • 1 << 0 is 00000001 in binary (value 1).
  • 1 << 1 is 00000010 in binary (value 2).
  • 1 << 2 is 00000100 in binary (value 4).
  • And so on.

Explanation of the Enum

The EffectFlags enum defines constants with specific meanings, as hinted by their names and comments. Here's what each flag might represent:

  1. ACTIVE = 1 << 0 (value: 1)

    • Indicates that the effect is active or enabled.
  2. RUNNING = 1 << 1 (value: 2)

    • Represents an effect that is currently running.
  3. TRACKING = 1 << 2 (value: 4)

    • Denotes that the effect is tracking dependencies (e.g., observing reactive data).
  4. NOTIFIED = 1 << 3 (value: 8)

    • Indicates the effect has been notified of a change.
  5. DIRTY = 1 << 4 (value: 16)

    • Suggests that the effect is "dirty" and needs to be re-evaluated (often due to changes in dependencies).
  6. ALLOW_RECURSE = 1 << 5 (value: 32)

    • Allows the effect to recurse (e.g., handle nested calls safely).
  7. PAUSED = 1 << 6 (value: 64)

    • Represents that the effect is paused and will not execute until resumed.

Why Use Bitwise Flags?

  • Efficiency: Bitwise flags allow multiple states to be represented in a single number, making checks and combinations very fast.

  • Combination: You can combine states using the bitwise | operator. For example:

const combined = EffectFlags.ACTIVE | EffectFlags.DIRTY;

This creates a combined state with both ACTIVE and DIRTY.

  • Checking: You can check for specific flags using the bitwise & operator:

if (combined & EffectFlags.DIRTY) {
  console.log('Effect is dirty');
}

Typical Usage

This kind of flag system is often used in libraries like Vue.js or Reactivity systems to manage and optimize dependency tracking, ensuring minimal recomputation by efficiently marking states.

For example, in Vue’s reactivity:

  • An effect might transition from ACTIVETRACKINGDIRTY.
  • Flags like NOTIFIED or PAUSED might be used during event handling or debugging.

相關文章