#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));