Перед выполнением другого кода убедитесь, что все контуры наблюдаемого в цикле - PullRequest
1 голос
/ 15 апреля 2019

У меня есть кусок кода, который выглядит следующим образом:

getPersons().subscribe(
    persons => {
        for (const person of persons) {
            getAddress(person.id).subscribe(
                address => {
                    person.address = address;
                }
            );
        }
        doSomethingWithAddresses();
     }
);

Проблема в том, что doSomethingWithAddresses выполняется до завершения всех наблюдаемых getAddress. Как вы можете убедиться, что все они завершены, прежде чем выполнять последующий код?

Ответы [ 3 ]

2 голосов
/ 15 апреля 2019

Вы должны использовать forkJoin RxJS, чтобы дождаться завершения цикла for..of перед возвратом всех наблюдаемых.

Вот изменения, которые вы должны внести в свой код:

getPersons().subscribe(
  persons => {
    const observablesList = [];
    for (const person of persons) {
      const getAddressObservable = getAddress(person.id);
      observablesList.push(getAddressObservable)
    }
    forkJoin(observablesList).subscribe(response => {
      // console.log(response) to check that there is a list of returned observables
      const result = persons.map((person, index) => {
        person['address'] = response[index]['address'];
        return person;
      })
      doSomethingWithAddresses();
    })
  }
);

В качестве альтернативы, вы можете попробовать это, чтобы предотвратить цепочку subscribe()

getPersons().pipe(
  mergeMap(persons => {
    const observablesList = [];
    for (const person of persons) {
      const getAddressObservable = getAddress(person.id);
      observablesList.push(getAddressObservable)
    }
    return observablesList;
  })
).subscribe(response => {
  // console.log(response) to check that there is a list of returned observables
  const result = persons.map((person, index) => {
    person['address'] = response[index]['address'];
    return person;
  })
  doSomethingWithAddresses();
})
0 голосов
/ 15 апреля 2019

Попробуйте этот подход

methodOne() {
getPersons().subscribe(
    persons => {
        for (const person of persons) {
            getAddress(person.id).subscribe(
                address => {
                    person.address = address;
                }
            );
        }
     }
);
}

async methodTwo() {
await methodOne();
doSomethingWithAddresses();
}
0 голосов
/ 15 апреля 2019
let loadedPerson;
getPersons().pipe(
  mergeMap(persons => {
  return of(persons);
}),
mergeMap(person => {
  loadedPerson = person;
  return getAddresses(person.id);
}),
map((address) => {
  loadedPerson.address = address;
}),
tap(()=>{
  doSomethingWithAddresses();
})
).subscribe();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...