Как вызвать http get service в компоненте, используя вывод другого http сервиса в Angular? - PullRequest
0 голосов
/ 11 октября 2018

Я очень плохо знаком с Angular и застрял в том, как вызывать службы СИНХРОННО ..

У меня две службы http GET, скажем, ServiceA и ServiceB , которые до сих пор вызывались по отдельности, успешно вызывались, т.е. были независимы друг от друга.

Но теперь из-за изменения требований я вынужден вызываться в цикле ServiceB сЗначение параметра передается из значения, возвращенного ранее путем вызова ServiceA внутри функции в файле компонента.

for(let i=0;i<3;i++){

    this.ServiceA.methodA().subscribe(result => {

    this.masterID= result.ID;

    console.log('Inside outer service');

     this.ServiceB.methodB(masterID).subscribe(
                    resultInner => {
                      child = resultInner.Text;
                      console.log('Inside Inner service');

                    });

    });

  }

Я пытаюсь передать значение, возвращенное ServiceA , хранящимся в переменнойmasterID в качестве параметра для внутреннего ServiceB и проверка порядка вызовов с помощью предупреждений, но они не вызываются синхронно.Наблюдаемое поведение состоит в том, что перед заполнением значения masterId успешным ответом, возвращаемым внешним ServiceA , вызывается внутренняя служба, т.е. ServiceB , и параметр paremeter masterID передается пустым, что дает неправильную функциональность.

Может кто-нибудь, пожалуйста, помогите заставить это вести себя правильно?

Наблюдаемое поведение в console.log ()

Inside Outer service
Inside Outer service
Inside Outer service

Inside Inner service
Inside Inner service
Inside Inner service

Ожидаемое поведение

Inside Outer service
Inside Inner service
Inside Outer service
Inside Inner service
Inside Outer service
Inside Inner service

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Вы должны потратить некоторое время на изучение rxjs, так как он довольно мощный, но поначалу немного сложный.В приведенном ниже примере я делаю следующее.

  • Используйте from() для создания массива элементов, имитирующих то, что вы делаете в вашем примере.
  • Используйте switchMap() дляпереключиться на новую наблюдаемую ServiceA.methodA()
  • Используйте map(), чтобы изменить поток от полного результата до только основного идентификатора.
  • Используйте switchMap, чтобы вызвать новый старт новой наблюдаемойс идентификатором, созданным в map().
  • Используйте касание, чтобы запустить побочный эффект от результата switchMap() с serviceB(), чтобы выполнить какое-либо действие с результатом.

Код

from(new Array(3)).pipe(
    switchMap(() => this.ServiceA.methodA()),
    tap(() => console.log('Inside outer service')),
    map(res => res.resultID),
    switchMap(masterID => this.ServiceB.methodB(masterID)),
    tap(() => console.log('Inside inner service')),
    tap(resultInner => {
         // doSomethingWith(resultInner);
         console.log(resultInner.Text);
    })
}).subscribe();

Я сохранил вызовы console.log() и поместил их в tap, чтобы вы могли видеть нужные результаты и удалять их из своего действующего производственного кода, когда вы 'готов.

0 голосов
/ 11 октября 2018

Единственная ошибка, которую я вижу, это то, что вы передаете masterId без this.masterId

this.ServiceA.methodA().subscribe(result => {
    this.masterID = result.ID;
    alert('Inside outer service');
    this.ServiceB.methodB(this.masterID).subscribe(
        resultInner => {
            child = resultInner.Text;
            alert('Inside Inner service');
        }
    );
});

EDIT , поскольку вы добавили цикл

someFunction(): Promise<any> {
    return new Promise((resolve, reject) => {
        this.ServiceA.methodA().subscribe(result => {
            this.masterID= result.ID;
            console.log('Inside outer service');

            this.ServiceB.methodB(masterID).subscribe(
                resultInner => {
                    child = resultInner.Text;
                    console.log('Inside Inner service');
                    return resolve(resultInner); // or whatever
                }
            );
        });
    });
}

async someFunction2(): Promise<any> {
    for(let i = 0; i < 3; i++) {
        await someFunction();
    }
}
...