map.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { Subscriber } from '../Subscriber';
  2. /**
  3. * Applies a given `project` function to each value emitted by the source
  4. * Observable, and emits the resulting values as an Observable.
  5. *
  6. * <span class="informal">Like [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map),
  7. * it passes each source value through a transformation function to get
  8. * corresponding output values.</span>
  9. *
  10. * <img src="./img/map.png" width="100%">
  11. *
  12. * Similar to the well known `Array.prototype.map` function, this operator
  13. * applies a projection to each value and emits that projection in the output
  14. * Observable.
  15. *
  16. * @example <caption>Map every click to the clientX position of that click</caption>
  17. * var clicks = Rx.Observable.fromEvent(document, 'click');
  18. * var positions = clicks.map(ev => ev.clientX);
  19. * positions.subscribe(x => console.log(x));
  20. *
  21. * @see {@link mapTo}
  22. * @see {@link pluck}
  23. *
  24. * @param {function(value: T, index: number): R} project The function to apply
  25. * to each `value` emitted by the source Observable. The `index` parameter is
  26. * the number `i` for the i-th emission that has happened since the
  27. * subscription, starting from the number `0`.
  28. * @param {any} [thisArg] An optional argument to define what `this` is in the
  29. * `project` function.
  30. * @return {Observable<R>} An Observable that emits the values from the source
  31. * Observable transformed by the given `project` function.
  32. * @method map
  33. * @owner Observable
  34. */
  35. export function map(project, thisArg) {
  36. return function mapOperation(source) {
  37. if (typeof project !== 'function') {
  38. throw new TypeError('argument is not a function. Are you looking for `mapTo()`?');
  39. }
  40. return source.lift(new MapOperator(project, thisArg));
  41. };
  42. }
  43. export class MapOperator {
  44. constructor(project, thisArg) {
  45. this.project = project;
  46. this.thisArg = thisArg;
  47. }
  48. call(subscriber, source) {
  49. return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
  50. }
  51. }
  52. /**
  53. * We need this JSDoc comment for affecting ESDoc.
  54. * @ignore
  55. * @extends {Ignored}
  56. */
  57. class MapSubscriber extends Subscriber {
  58. constructor(destination, project, thisArg) {
  59. super(destination);
  60. this.project = project;
  61. this.count = 0;
  62. this.thisArg = thisArg || this;
  63. }
  64. // NOTE: This looks unoptimized, but it's actually purposefully NOT
  65. // using try/catch optimizations.
  66. _next(value) {
  67. let result;
  68. try {
  69. result = this.project.call(this.thisArg, value, this.count++);
  70. }
  71. catch (err) {
  72. this.destination.error(err);
  73. return;
  74. }
  75. this.destination.next(result);
  76. }
  77. }
  78. //# sourceMappingURL=map.js.map