Rx JS: Разница между AuditTime и sampleTime? - PullRequest
2 голосов
/ 03 мая 2020

Я не могу найти соответствующие сообщения об этом, и я не могу выяснить нюанс из документации, в чем разница между операторами auditTime и sampleTime?

1 Ответ

3 голосов
/ 03 мая 2020

auditTime

auditTime(ms) будет хранить последнее значение в течение ms миллисекунд. После того, как ms прошло, если какое-либо значение существует, оно передаст как next notification.

auditTime(ms) === audit(() => timer(ms, scheduler?)).

u - units of time

1--3--5----------6-7-- values$
----|-----|----!-----| auditTime(5u)
----3-----5----------7 result

^     ^          ^

! - since the timer did not started, because there was no value after `5`, there won't be any value emitted further in the stream

^ - when the timer starts

Стоит также отметить, что это Таймер запускается только при получении хотя бы одного значения.

Возможно, визуализация исходного кода поможет:

_next(value: T): void {
  this.value = value; // Keep track of the oldest value
  this.hasValue = true;
  if (!this.throttled) { // If the timer didn't started yet, start it
    let duration;
    try {
      const { durationSelector } = this;
      duration = durationSelector(value); // Create observable; if `auditTime(d)`, it will be `() => timer(ms)`
    } catch (err) {
      return this.destination.error(err);
    }
    const innerSubscription = subscribeToResult(this, duration); // Subscribe to the inner observable
    /* ... */
    this.throttled = innerSubscription // Store the subscription
  }
}

Когда истечет таймер (т.е. когда внутренняя наблюдаемая была отправлена ​​/ завершена), значение будет передано:

// Called when the inner obs completes/emits a value
clearThrottle() {
  const { value, hasValue, throttled } = this;
  if (throttled) { // Did we have a timer(a subscription)? If yes, unsubscribe 
    this.remove(throttled);
    this.throttled = null;
    throttled.unsubscribe();
  }
  if (hasValue) { // If we have a value, send it do its destination
    this.value = null;
    this.hasValue = false;
    this.destination.next(value);
  }
}

sampleTime

sampleTime(ms), например, auditTime(ms) будет отслеживать последние поступившие значение и будет выдавать его далее в цепочке, за исключением , что в sampleTime timer (который решает, когда emit значение) всегда активен. Это означает, что независимо от того, поступило ли какое-либо значение, поступившее после последнего выброса , таймер будет работать. Теперь, если новое значение не поступило, оно просто не передаст значение.

Давайте рассмотрим его исходный код :

_next(value: T) { // Keep track of the oldest value
  this.lastValue = value;
  this.hasValue = true;
}

notifyNext() { // When time is up, check if any `new` value came in since the last 'sample' 
  if (this.hasValue) { // If we have a value, then send it further
    this.hasValue = false;
    this.destination.next(this.lastValue);
  }
}

Обратите внимание, что значение может быть такой же, как тот, который был выдан ранее, но он должен прибыть, когда текущий таймер активен.

sampleTime по умолчанию использует AsyncAction s, которыми управляет с помощью AsyncScheduler. Иными словами, timer, в этом случае, достигается с setInterval.

sample(notifier), следует тому же логу c, за исключением того, что нет планировщика, и определено timer notifier, то есть Observable.

По сравнению с auditTime:

u - units of time

1--3--5-------6-7-- values$
----|---|---|---|-- auditTime(5u)
----3---5-------7-- result

^   ^   ^   ^   ^

^ - when the timer starts
...