Как вы динамически устанавливаете свойство класса с помощью axios all?

#javascript #node.js #axios

#язык JavaScript #node.js #аксиос

Вопрос:

У меня есть звуковой проигрыватель для уведомлений в моем веб-приложении. Я использую CakePHP в качестве серверной части и webpack для интерфейса. Я пытаюсь создать файл класса, который сначала получит звуковые настройки текущего пользователя при создании экземпляра объекта, а затем метод в классе Sound.

Сначала я начинаю с вызова axios в конструкторе. Я предполагаю, что конструктор будет ждать завершения вызова axios, прежде чем что-либо делать. Но когда я запускаю что-то вроде:

 const sound = new Sound(); sound.playTone(Sound.MESSAGE);  

Все, что я получаю, — это проблема с попыткой вставить обещание в путь, по которому сервер воспроизводит звук. Я нахожусь на 2-м дне попыток разобраться в этом и попытался использовать асинхронность и ожидание для запуска playTone (), но он все еще работает неправильно.

ВАЖНО: Я пытаюсь в конечном итоге сделать так, чтобы приложение могло загружать все настройки сразу, чтобы один и тот же объект можно было создать один раз, а затем воспроизвести необходимые тона, потому что вы можете видеть несколько тонов. Я не хочу каждый раз спрашивать сервер, что это за сигнал, из-за проблем с пропускной способностью, которые могут начать возникать.

 "use strict";  import axios from "axios";  /**  * Sounds class  */ export class Sound {  /**  * Message flag  *  * @type {string}  */  static MESSAGE = 'message';   /**  * Email flag  *  * @type {string}  */  static EMAIL = 'email';   /**  * Error flag  *  * @type {string}  */  static ERROR = 'error';   /**  * Class constructor  */  constructor()  {  axios.get('/preferences/get-message-preference')  .then(response =gt; {  this._messagePath = response.data.value;  })  .catch(err =gt; {  this._messagePath = 'tweet-416';  console.error(`Could not get preference: ${err}`)  })  .finally(() =gt; {  console.log(`Test completed: ${this.messagePath}`)  })  }   get messagePath()  {  return this._messagePath;  }   /**  * Play Alert Tone  *  * Play a tone in the client to indicate something the user should direct heir attention to.  * Use sparingly!  *  * @param {string} type Classification of the tone that should be played.  * @return {Promiselt;voidgt;} Promise is also caught in the method.  */  playTone = (type) =gt; {   return new Audio(`/material/fx/${this.#getPath(type)}.mp3`)  .play()  .catch(error =gt; {  if (error.name === 'NotAllowedError')  console.warn('Could not play sound. Interaction requirements not met');  else console.error(`Could not play sound: ${error.name}`);  });  }   /**  * Get Tone File Path  *  * Get the relative/web path for the sound tone file.  *  * @param {string} type The classification of the tone.  * @return {string} Relative/web path for the sound tone file specified.  */  #getPath = (type) =gt; {  switch (type) {  case Sound.MESSAGE:  return this.messagePath;  case Sound.EMAIL:  case 'your-turn-491':  return 'your-turn-491';  case Sound.ERROR:  case 'long-expected-548':  return 'long-expected-548';  case 'Pop-Tone':  default:  return 'Pop-Tone';  }  } }   

Ответ №1:

Это лучшее решение, которое я мог бы придумать, но оно все равно кажется менее убедительным

 /**  * Class constructor  */  constructor()  {  this._messagePath = 'tweet-416';  }   init = async () =gt; {  return await axios.get('/preferences/get-message-preference')  .then(response =gt; response.data)  .then(data =gt; {  this._messagePath = data.value;  })  .catch(err =gt; {  this._messagePath = 'tweet-416';  console.error(`Could not get preference: ${err}`)  })  .finally(() =gt; {  console.log(`Test completed: ${this.messagePath}`)  })  }   

Это создает обещание, которое работает с тем фактом, что сначала нам нужно дождаться ответа axios. Затем мы меняем способ запуска системы.

 const sound = new Sound(); sound.init().then(() =gt; sound.playTone(Sound.MESSAGE));