Пусть вызов await для асинхронного метода будет ждать завершения - PullRequest
2 голосов
/ 06 июня 2019

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

public async getSomeMidiNotes(): Promise<Array<number>> {
  const notes: Array<number> = new Array<number>();
  await this.getRandomMidiNotes()
  .pipe(
    take(500)
  )
  .subscribe(note => {
    notes.push(note);
  });
  return notes;
}

public getRandomMidiNotes(): Observable<number> {
  return interval(MIDI_NOTE_DURATION)
    .pipe(
      map(data => Math.floor(Math.random() * MIDI_NOTE_MAX) + MIDI_NOTE_MIN)
    );
}

Я использую его для возврата массива:

const gotes: Array<number> = await this.generatorService.getSomeMidiNotes();
console.log(gotes);

Но массив, отображаемый в консоли браузера, всегда имеет разную длину, иногда 2 элемента, иногда 50 и т. Д. *

Я бы хотел, чтобы массив был полностью укомплектован 500 элементами перед его возвратом.

1 Ответ

0 голосов
/ 06 июня 2019

рабочий код

public async getSomeMidiNotes(): Promise<Array<number>> {
  const notes: Array<number> = new Array<number>();

  return getRandomMidiNotes().pipe(
    take(500),
    map(note => {
      notes.push(note);
      return notes;
    })
  ).toPromise();
}

Использование:

const notes: Array<number> = await this.generatorService.getSomeMidiNotes();
console.log(notes);

Реализация стекаблица: https://stackblitz.com/edit/rxjs-fcmzrp

Пояснения

Функция mapвставьте элементы в массив заметок и верните его.toPromise позволяет вам преобразовать наблюдаемое в обещание.В этом случае он возвращает обещание и, когда вы позвоните getSomeMidiNotes, вы сможете использовать await.

...