У меня есть несколько сообщений http, которые извлекают данные JSON из базы данных MySQL. Я хочу, чтобы функция прослушивала их все и запускала следующий фрагмент кода, как только все они возвращали, что данные были получены.
Я пробовал несколько вариантов async с ожиданием, но функция, похоже, не ожидает завершения HTTP-сообщения.
У меня есть служба риска Risk.service.ts, чтобы получить, например, RiskTable:
getRiskTable(): Observable<Risk[]> {
return this.http.get(`${this.baseUrl}/getRiskTable`).pipe(
map((res) => {
this.riskTable = res['data'];
return this.riskTable;
}),
catchError(this.handleError));
}
На моей панели инструментов я называю этот код:
getRiskTable():any {
return this.riskService.getRiskTable().subscribe(
(res: []) => {
this.riskTable = res; // the value is correctly captured here
return true;
},
(err) => {
this.error = err;
}
);
}
И затем асинхронная функция, которая запускает несколько из этих функций, теоретически предполагается, что она должна дождаться завершения всех функций, а затем зарегистрировать значение. Но почему-то глобальная переменная this.riskTable в этой функции не определена.
async getAllData(){
let riskTable = await this.getRiskTable();
let risks = await this.getAllRisks();
console.info(riskTable); //This returns stuff
console.info(risks);
console.info(this.riskTable); //This returns undefined even though it was set in getRiskTable
}
Пожалуйста, любые указатели - я очень новичок в angular, и сложность этого меня полностью озадачила. 2 дня и 100-кратные вариации, чтобы заставить это работать Я медленно теряю свои бананы!
Хорошо, я быстро просмотрел найденный и пример forkJoin. Они запустили его в службе, чтобы получить все HTTP-запросы, а затем вернуть результат. У меня есть несколько вызовов HTTP, которые должны оставаться модульными. Я хотел бы вызывать их один за другим из разных компонентов, и именно по этой причине я хочу, чтобы компонент мог получить доступ к данным из службы и дождаться их завершения (параллельно было бы идеально, но я возьму что угодно в этот момент).





Поскольку вы используете Angular, вы должны использовать forkJoin RxJS, чтобы объединить наблюдаемые из обоих методов запроса API в одно наблюдаемое значение и вернуть ему значения с помощью подписка.
Не забудьте импортировать forkJoin в свой компонент.
import { forkJoin } from 'rxjs';
..
getAllData(){
const riskTable = this.riskService.getRiskTable();
const risks = this.riskService.getAllRisk();
forkJoin(riskTable, risks).subscribe(response => {
console.info(response);
})
}
Если вы настаиваете на обработке его как промиса, а не как наблюдаемого, вы можете использовать Обещание.все(), который возвращает их как один промис.
Во-первых, ключевые слова async/await используются с обещаниями, а не с Observable. Таким образом, вы можете преобразовать наблюдаемое в обещание, используя toPromise(), или вы можете использовать rxjs ForkJoin. Вам также нужно изменить методы, чтобы возвращать либо наблюдаемое, либо обещание, вы мало что можете сделать с подпиской, которую возвращает subscribe, когда вы ее вызываете, и это то, что вы сейчас передаете из getRiskTable.
Еще одна проблема заключается в том, что вы не используете преимущества системы типов, не используйте any везде, потому что эти ошибки могли быть обнаружены во время транспиляции, и теперь вам нужно догадаться, почему это происходит во время выполнения, что сложнее.
import { forkJoin } from 'rxjs';
import { shareReplay } from 'rxjs/operators';
getRiskTable() : Observable<Risk[]> {
const tableObservable = this.riskService.getRiskTable().pipe(shareReplay());
tableObservable.subscribe((res) => this.riskTable = res, (err) => {this.error = err;});
return tableObservable;
}
getAllData() {
let riskTable = this.getRiskTable();
let risks = this.getAllRisks(); // should also return some observable
forkJoin(riskTable, risks).subscribe(_ => {
// all observables have been completed
});
}
Обратите внимание, что я также добавил shareReplay, который гарантирует, что несколько подписок на один и тот же наблюдаемый объект не приведут к нескольким вызовам конечной точки вашего API. Один результат распределяется между несколькими подписками на наблюдаемое.
Игорь, сейчас 3 часа ночи. Я чертовски счастлива прямо сейчас, что написала тебе вот это кое-что: Я дизайнер Глупый, визуальный и Немного нытик Дела пошли действительно тяжело Слава Богу Игорь пришел И дал код love @_@ !! 10/10 Люблю тебя!
@BrendenEngelbrecht - рад, что у вас все заработало, и я надеюсь, что это все еще имеет смысл утром (после того, как вы немного отдохнете) :)
ваша первая функция getRisk возвращает наблюдаемое, а не обещание, вам нужно сделать .toPromise(), чтобы преобразовать наблюдаемое в обещание. ваша вторая функция getRiskTable подписалась на наблюдаемую, которая очень непоследовательна по сравнению с вашей первой, вы должны делать то же самое, что и ваша первая функция, только возвращать обещание, тогда ваше асинхронное ожидание должно работать.
или вы можете использовать forkjoin(obs1,obs2), зависит от ваших интересов, но оставайтесь последовательными.
Вы можете подумать о
forkJoin, который выполняется параллельно (если ни один из них не зависит друг от друга), и в обратном вызове вы можете делать с данными все, что вам нужно.