2 votes

Rxjs TypeError : this._complete n'est pas une fonction

Je suis en train d'apprendre à écrire un opérateur rxjs, quand j'écris comme ceci :

function map(project: (value: T) => R): OperatorFunction {
  return function mapOperation(source$: Observable): Observable {
    if (typeof project !== "function") {
      throw new TypeError("l'argument n'est pas une fonction...");
    }
    return Observable.create((observer: Observer) => {
      console.log(observer.complete);
      const subscription = source$.subscribe({
        next: value => {
          try {
            observer.next(project(value));
          } catch (e) {
            observer.error(e);
          }
        },
        error: observer.error,
        complete: observer.complete // ici
      });
      return () => {
        subscription.unsubscribe();
      };
    });
  };
}

const source$ = of(1, 2, 3);
map((x: number) => x * x)(source$).subscribe(console.log);

ça ne fonctionne pas :

 this._complete();
           ^
TypeError: this._complete n'est pas une fonction
    à Object.Subscriber.complete (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:126:12)
    à Object.wrappedComplete (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:248:54)
    à SafeSubscriber.__tryOrUnsub (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:265:10)
    à SafeSubscriber.complete (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:251:16)
    à Subscriber._complete (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:148:22)
    à Subscriber.complete (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Subscriber.ts:126:12)
    à Observable._subscribe (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/util/subscribeToArray.ts:11:14)
    à Observable._trySubscribe (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Observable.ts:238:19)
    à Observable.subscribe (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/node_modules/rxjs/src/internal/Observable.ts:219:14)
    à Observable._subscribe (/Users/ahabhgk/moby-dick/FE/some-note/deep-in-rxjs/index.ts:10:36)

mais quand je change complete: observer.complete en complete: () => observer.complete(), ça marche

function map(project: (value: T) => R): OperatorFunction {
  return function mapOperation(source$: Observable): Observable {
    if (typeof project !== "function") {
      throw new TypeError("l'argument n'est pas une fonction...");
    }
    return Observable.create((observer: Observer) => {
      console.log(observer.complete);
      const subscription = source$.subscribe({
        next: value => {
          try {
            observer.next(project(value));
          } catch (e) {
            observer.error(e);
          }
        },
        error: observer.error,
        complete: () => observer.complete() // ici
      });
      return () => {
        subscription.unsubscribe();
      };
    });
  };
}

const source$ = of(1, 2, 3);
map((x: number) => x * x)(source$).subscribe(console.log);

pourquoi y a-t-il une différence entre complete: observer.complete et complete: () => observer.complete(), ce sont toutes des fonctions

2voto

Wilt Points 867

observer.complete est appelé dans un scope différent lorsque vous utilisez votre fonction fléchée complete: () => observer.complete() et lorsque vous utilisez complete: observer.complete.

La méthode complete() de l'observateur appelle _complete() en interne dans le scope d'exécution de la fonction, this._complete().

Dans votre fonction fléchée cela fonctionnera car vous appelez la méthode sur l'instance de l'objet observer, ce qui signifie qu'elle s'exécute dans le bon scope (le scope de l'observateur) alors que cela ne fonctionne pas dans l'autre cas car il est appelé dans le scope du souscripteur et il n'y a pas de méthode _complete définie dans ce scope, d'où l'erreur est lancée.

Vous pourriez également faire ceci:

complete: observer.complete.bind(observer),

avec la méthode bind vous pouvez lier la méthode complete au bon scope, le scope de l'observateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X