Forkjoin, сопровождаемый foreach, вызывает «Невозможно вызвать выражение, тип которого не имеет подписи вызова». - PullRequest
0 голосов
/ 26 февраля 2020

При попытке подписаться на результат forkJoin внутри функции onInit я получаю следующую ошибку:

ошибка TS2349: Невозможно вызвать выражение, тип которого не имеет подписи вызова. Тип '((следующий: (значение: Result []) => void, promiseCtor ?: PromiseConstructorLike) => Promise) | ((следующее: (значение: Account []) => void, promiseCtor ?: PromiseConstructorLike) => Promise) 'не имеет совместимых подписей вызовов.

getAccounts возвращает наблюдаемую учетную запись [], getResults возвращает наблюдаемый результат []. Когда обе загрузки завершены, я пытаюсь получить подробные результаты учетной записи из другой базы данных, используя accessToken учетных записей, полученных из функции getAccounts, чтобы я мог добавить результаты в подробные учетные записи.

Короче говоря, я пытаюсь добиться этого:

let var = getAccountsSimplified();
let var2 = getAllResults();

if both are finished{
    foreach(acc in var) {
        account = getDetailedAccount(acc.id)
        var ownedResults = var2.where(userid === acc.id)
        account.results = ownedResults
    }
}

Это то, что я пытался до сих пор, но по какой-то причине это вызывает ошибку, упомянутую выше. По какой-то причине console.log(user) работает нормально, поэтому я совершенно заблудился при ошибке.


const tasks$ = [
      this.aus.getAccounts(this.auth.token),
      this.rs.getResults(this.auth.token)
    ];

    forkJoin(tasks$).subscribe(
      value => {
        const userList = value[0];
        const resultList = value[1];
        userList.forEach((acc: Account) => {
          this.aus.getUserDetails(acc.access_token).subscribe((user: User) => {
            if (user != null) {
              console.log(user);
            }
          });
        });
      }
    );

Сигнатуры вызываемых функций:

  getAccounts(auth: string): Observable<Array<Account>> {
  }

  getResults(auth: string): Observable<Array<Result>> {
  }

  getUserDetails(token: string): Observable<User> {
  }

Обновление
После добавления предложения Курта я теперь получаю

Аргумент типа 'MonoTypeOperatorFunction <[Account [], Result []]>' нельзя назначить параметру типа ' OperatorFunction <(Observable | Observable) [], [Account [], Result []]> '. Типы параметров «источник» и «источник» несовместимы. Тип «Observable <(Observable | Observable) []>» нельзя назначить типу «Observable <[Account [], Result []]>». В типе '(Observable | Observable) []' отсутствуют следующие свойства из типа '[Account [], Result []]': 0, 1ts (2345)

Кажется, что существует проблема с возвращенным типом forkjoin.

Update 2
Оказалось, что удаление массива задач $ и добавление функций непосредственно в forkjoin решило проблему.

1 Ответ

1 голос
/ 26 февраля 2020

Попробуйте преобразовать вложенную подписку в switchMap.

. Я реорганизовал ваш пример так:

  1. Сохраните resultList в какую-либо переменную или свойство - это может использовать позже
  2. Передать userList на switchMap
  3. Использовать switchMap на forkJoin все вызовы на getUserDetails
  4. Массив пользовательские данные теперь поступают в вашу подписку, и у вас есть доступ к списку результатов
const tasks$ = [
  this.getAccounts(),
  this.getResults()
];

forkJoin(tasks$).pipe(
  tap((value: [ Account[], Result[] ]) => this.resultList = value[1]),
  map((value: [ Account[], Result[] ]) => value[0]),
  switchMap(accounts => forkJoin(
    accounts.map(x => this.getUserDetails(x.access_token))
  ))
).subscribe(details => {
  this.userList = details.filter(x => !!x);
  console.log(this.resultList);
});

Этот пример из моей демонстрации ниже, которая демонстрирует концепцию, а не ваши точные вызовы и настройку.

DEMO: https://stackblitz.com/edit/angular-viewbm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...