Mam funkcję zwaną getDevices(), która pobiera tablicę urządzeń, itera za pomocą każdego urządzenia i wywołania updateToServer(), która aktualizuje te urządzenia do serwera. Muszę strzelać inną metodę po wszystkich obserwowaniach updateToServer w pętli są rozwiązane, jak mogę to osiągnąć?

this.deviceService.getDevices().then((res : devicesInterface) => {
      if(res){        

        this.devices = res.devices;   

        this.devices.forEach(device => {  

          let data : ResUpdateDevices = {
            device: device,
            token: this.authenticationService.getToken(),
          };

          this.deviceService.updateDevicesToServer(data).subscribe(res => {
            console.log(res)  
          },err=>{
            console.log(err)
          });
        });

      } 
    })

Czytałem na forum o metodzie {X0}}, ale nie znalazłem żadnego przykładu pracy.

1
Rishabh Gusain 1 marzec 2019, 19:18

2 odpowiedzi

Najlepsza odpowiedź

Użyj {x0}}

Dlaczego warto używać widłoin?

Ten operator jest najlepiej wykorzystany, gdy masz grupę obserwownictwa i dbasz tylko o ostateczną wartość emitowaną każdej. Jeden wspólny przypadek użycia dla tego jest to, że chcesz wydać wiele żądań na obciążeniu strony (lub innym wydarzeniem) i chcesz podjąć działania, gdy odpowiedź została odebrana dla wszystkich. W ten sposób jest podobny do tego, jak możesz użyć Promise.all.

Należy pamiętać, że jeśli którykolwiek z wewnętrznych obserwatorów dostarczył błąd widłowy, utracisz wartość wszelkich innych obserwatorów, które byłyby już zakończone, jeśli nie przyciągnij błąd prawidłowo na wewnętrznym obserwowalnym. Jeśli jesteś zainteresowany tylko wszystkimi obserwatorstwami wewnętrznymi, które pomyślnie ukończysz, możesz złapać błąd na zewnątrz.

Stackblitz

Twój kod

import { forkJoin } from 'rxjs';
import { tap } from 'rxjs/operators';

this.deviceService.getDevices().then((res : devicesInterface) => {
  if(res){        

    this.devices = res.devices;
    // use map instead of foreach to return a result
    var allObservables = this.devices.map(device => {  

        let data : ResUpdateDevices = {
            device: device,
            token: this.authenticationService.getToken(),
        };

        // return Observable
        return this.deviceService.updateDevicesToServer(data).pipe(tap(res => {
              console.log(res);  
          },err=>{
              console.log(err);
          }));
    });

    // call forkJoin on returned observables
    forkJoin(allObservables).subscribe(() => /* do something here */);
  } 
})
3
Igor 1 marzec 2019, 16:41

Aby zrobić to, co próbujesz osiągnąć, obserwowały będą naprawdę pomocne. Coś takiego powinno działać (nie przetestowałem):

    // make getDevices() to return an observable, or if you can't use 'from' to create a new Observable from a promise
    this.deviceService.getDevices()
        .pipe(
          flatMap(d => d), // each items from array emitted one by one
          map(device => {  
            let data : ResUpdateDevices = {
              device: device,
              token: this.authenticationService.getToken(),
            };
            return this.deviceService.updateDevicesToServer(data);
          }),
          tap(res => /*do something else without updating value emitted by Observable*/)
        ).subscribe(res => {
          // do something
          console.log(res);
        }, err=>{
          console.log(err)
        });
2
maxsoulard 2 marzec 2019, 12:27