skipLast.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import { Subscriber } from '../Subscriber';
  2. import { ArgumentOutOfRangeError } from '../util/ArgumentOutOfRangeError';
  3. /**
  4. * Skip the last `count` values emitted by the source Observable.
  5. *
  6. * <img src="./img/skipLast.png" width="100%">
  7. *
  8. * `skipLast` returns an Observable that accumulates a queue with a length
  9. * enough to store the first `count` values. As more values are received,
  10. * values are taken from the front of the queue and produced on the result
  11. * sequence. This causes values to be delayed.
  12. *
  13. * @example <caption>Skip the last 2 values of an Observable with many values</caption>
  14. * var many = Rx.Observable.range(1, 5);
  15. * var skipLastTwo = many.skipLast(2);
  16. * skipLastTwo.subscribe(x => console.log(x));
  17. *
  18. * // Results in:
  19. * // 1 2 3
  20. *
  21. * @see {@link skip}
  22. * @see {@link skipUntil}
  23. * @see {@link skipWhile}
  24. * @see {@link take}
  25. *
  26. * @throws {ArgumentOutOfRangeError} When using `skipLast(i)`, it throws
  27. * ArgumentOutOrRangeError if `i < 0`.
  28. *
  29. * @param {number} count Number of elements to skip from the end of the source Observable.
  30. * @returns {Observable<T>} An Observable that skips the last count values
  31. * emitted by the source Observable.
  32. * @method skipLast
  33. * @owner Observable
  34. */
  35. export function skipLast(count) {
  36. return (source) => source.lift(new SkipLastOperator(count));
  37. }
  38. class SkipLastOperator {
  39. constructor(_skipCount) {
  40. this._skipCount = _skipCount;
  41. if (this._skipCount < 0) {
  42. throw new ArgumentOutOfRangeError;
  43. }
  44. }
  45. call(subscriber, source) {
  46. if (this._skipCount === 0) {
  47. // If we don't want to skip any values then just subscribe
  48. // to Subscriber without any further logic.
  49. return source.subscribe(new Subscriber(subscriber));
  50. }
  51. else {
  52. return source.subscribe(new SkipLastSubscriber(subscriber, this._skipCount));
  53. }
  54. }
  55. }
  56. /**
  57. * We need this JSDoc comment for affecting ESDoc.
  58. * @ignore
  59. * @extends {Ignored}
  60. */
  61. class SkipLastSubscriber extends Subscriber {
  62. constructor(destination, _skipCount) {
  63. super(destination);
  64. this._skipCount = _skipCount;
  65. this._count = 0;
  66. this._ring = new Array(_skipCount);
  67. }
  68. _next(value) {
  69. const skipCount = this._skipCount;
  70. const count = this._count++;
  71. if (count < skipCount) {
  72. this._ring[count] = value;
  73. }
  74. else {
  75. const currentIndex = count % skipCount;
  76. const ring = this._ring;
  77. const oldValue = ring[currentIndex];
  78. ring[currentIndex] = value;
  79. this.destination.next(oldValue);
  80. }
  81. }
  82. }
  83. //# sourceMappingURL=skipLast.js.map