вызовите синхронный вызов внутри l oop, дождитесь, пока два вызова API получат успех, затем в angular 6 должна начаться следующая итерация - PullRequest
3 голосов
/ 17 января 2020

Пробовал с приведенным ниже кодом, не дожидаясь успешного завершения вызова после перехода к следующей итерации до получения ответа. Требование: необходимо выполнить следующую итерацию после успешного выполнения двух вызовов API (POST / PATCH)

 for (item of data) {
  A(item)

}
A(value) {
  const resp = this.post(url, {
      'rationale': value['rationale']
    })
    .mergeMap(tempObj => {
      value['detail'] = tempObj['id']
      return this.patch(url, value['extid'], value)
    })
    .subscribe()
}

Ответы [ 3 ]

1 голос
/ 17 января 2020

Недавно я использовал функцию toPromise с angular http, чтобы превратить наблюдаемое в обещание. Если у вас есть внешняя l oop внутри функции asyn c, это может работать:

// This must be executed inside an async function
for (item of data) {
  await A(item)
}

async A(value) {
  const resp = await this.post(url, {
      'rationale': value['rationale']
    })
    .mergeMap(tempObj => {
      value['detail'] = tempObj['id']
      return this.patch(url, value['extid'], value)
    }).toPromise();
}
0 голосов
/ 18 января 2020

Вы можете использовать:

<form (ngSubmit)="submit$.next(form.value)" ...

В вашем компоненте:

submit$= new Subject();

ngOnInit {
submit$.pipe(
        exhaustMap(value => 
            this.post(url, {'rationale': value.rationale}))
            .pipe(concatMap( response => {
                value.detail = response.id;
                return this.patch(url, value.extid, value);
        }))).subscribe(); // rember to handle unsubcribe
}

Причина, по которой я обычно использую выхлопную карту, обычно post и path - это мутирующие вызовы, так что оператор гарантирует, что первая отправка будет обработана игнорируйте все остальное при обработке AKA, избегайте двойной отправки

Еще лучше использовать эффекты ngrx, которые, если вы еще этого не знаете, я рекомендую изучить

submit$ = createEffect(
() => this.actions$.pipe(
    ofType(FeatureActions.submit),
    exhaustMap( ({value}) => // if action has value property
            this.post(url, { rationale : value.rationale}))
            .pipe(concatMap( response => {
                value.detail = response.id;
                return this.patch(url, value.extid, value);
        })),
    map(result => FeatureActions.submitSuccess(result))
)
);
0 голосов
/ 18 января 2020

Используйте from для вывода элементов массива. Используйте concatMap для сопоставления с Наблюдаемой и только для сопоставления со следующим после завершения предыдущего.

const resp$ = from(data).pipe(
  concatMap(value => this.post(url, { 'rationale': value['rationale'] }).pipe(
    switchMap(tempObj => {
      value['detail'] = tempObj['id']
      return this.patch(url, value['extid'], value)
    })
  ))
)

Я использовал switchMap вместо mergeMap, чтобы указать, что функция mergeMap для запуск нескольких Observables одновременно не используется.

...