преобразовать функцию const asyn c в React - PullRequest
0 голосов
/ 26 мая 2020

У меня есть класс React, в котором я беру ванильную программу js и пытаюсь реализовать ее как класс React. Конечным состоянием должен быть генератор musi c.

Прямо сейчас я получаю звук, и это здорово, но это просто последовательность c. Самое интересное - это функция const asyn c. Поскольку я новичок в интерфейсе в целом, я не уверен, как преобразовать функцию const asyn c в полезную часть компонента реакции, чтобы она не просто воспроизводила последовательность нот, а фактически запускала rnn.

Это класс:

class Beat3 extends React.Component {
  constructor(props) {
    super(props);
    this.improvCheckpoint = 'https://storage.googleapis.com/magentadata/js/checkpoints/music_rnn/chord_pitches_improv'
    this.improvRNN = new mm.MusicRNN(this.improvCheckpoint)
    this.synth = new Tone.Synth().toMaster()
    const { midi, Note } = Tonal
    this.player = new mm.Player();

    this.sequence = {
      BEATB: {
      ticksPerQuarter: 360,
      totalTime: 2,
      timeSignatures: [{ time: 0, numerator: 4, denominator: 4 }],
      tempos: [{ time: 0, qpm: 300 }],
      notes: [
        { pitch: 60.3, startTime: 0, endTime: 0.9 },
        { pitch: 65.4, startTime: 0.9, endTime: 1.9 },
        { pitch: 67.2, startTime: 1.9, endTime: 2.7 },
      ]
    }
  }

    this.quantizedSequence = mm.sequences.quantizeNoteSequence(this.sequence, 1)

    /*This is what Im trying to have run in the react class*/

    const startProgram = async () => {
    try {
    await this.improvRNN.initialize()
    let improvisedMelody = await this.improvRNN.continueSequence(
      this.quantizedSequence, 60, 1.1, [60, 75,67,69])

    const playOriginalMelody = () => {
      this.sequence.notes.forEach(note => {
        this.synth.triggerAttackRelease(Note.fromMidi(note.pitch),
        note.endTime - note.startTime, note.startTime)
      })
    }

    const playGeneratedMelody = () => {
      improvisedMelody.notes.forEach(note => {
        this.synth.triggerAttackRelease(Note.fromMidi(note.pitch),
        note.quantizedEndStep - note.quantizedStartStep, note.quantizedStartStep)
      })
    }

    const originalMelodyButton = document.getElementById('b1a')
    const generatedMelodyButton = document.getElementById('b1b')
    originalMelodyButton.onclick = () => {
      playOriginalMelody()
    }
    generatedMelodyButton.onclick = () => {
      playGeneratedMelody()
    }

  } catch (error) {
    console.error(error)
  }
 }
}

  componentDidMount() {
    this.player.start(this.sequence.BEATB);
  }

  componentWillUnmount() {
    this.player.stop();
  }

  render()
  {
    return (
      <div class="b1a">
      </div>
    );
  }
}

export default Beat3

Когда я добавляю asyn c в componentDidMount, звук все равно появляется, но кнопки const внутри не отображаются. Я уверен, что это легко исправить, и объяснение того, что здесь делать, было бы очень полезно.

componentDidMount with asyn c:

componentDidMount() {
    this.player.start(this.sequence.BEATB);
    const startProgram = async () => {
    try {
    await this.improvRNN.initialize()
    let improvisedMelody = await this.improvRNN.continueSequence(
      this.quantizedSequence, 60, 1.1, [60, 75,67,69])
    const playOriginalMelody = () => {
      this.sequence.notes.forEach(note => {
        this.synth.triggerAttackRelease(Note.fromMidi(note.pitch),
        note.endTime - note.startTime, note.startTime)
      })
    }
    const playGeneratedMelody = () => {
      improvisedMelody.notes.forEach(note => {
        this.synth.triggerAttackRelease(Note.fromMidi(note.pitch),
        note.quantizedEndStep - note.quantizedStartStep, note.quantizedStartStep)
      })
    }
    const originalMelodyButton = document.getElementById('b1a')
    const generatedMelodyButton = document.getElementById('b1b')
    originalMelodyButton.onclick = () => {
      playOriginalMelody()
    }
    generatedMelodyButton.onclick = () => {
      playGeneratedMelody()
    }
  } catch (error) {
    console.error(error)
  }
}
}

Как всегда, любая помощь оценен.

1 Ответ

1 голос
/ 26 мая 2020

Если вы хотите вызвать функцию startProgram из ComponentDidMount (когда компонент загружен в приложение):

async componentDidMount() {
    this.player.start(this.sequence.BEATB);

    await startProgram();
}

Однако примите во внимание, что обычно лучше всего назначать поведение кнопкам в Реагировать следует, объявив их в JSX в функции render() и назначив поведение с помощью свойства onClick.

Например, первой кнопке (которая на самом деле является div) можно добавить свое поведение вот так (вам нужно, чтобы playOriginalMelody был объявлен на уровне класса или внутри render()):

render()
{
  return (
    <div class="b1a" onClick={playOriginalMelody}>
    </div>
  );
}
...