Intento crear un efecto de aparición y desaparición gradual para una aplicación de música cuando hago clic en el botón siguiente/anterior; Tengo esta función de suspensión:
const sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));la función cuando se presiona el botón:
function nextSong() { songIndex++; if (songIndex > songs.length - 1) { songIndex = 0; } fadeOut(audio); loadSong(songs[songIndex]); playSong(); fadeIn(audio); }y las funciones de desvanecimiento
async function fadeOut(soundtrack){ for (var i = 1.0; i > 0; i-= 0.01) { console.log(i); console.log(soundtrack.volume); soundtrack.volume = i; await sleep(2000); } } async function fadeIn(soundtrack){ for (var i = 0; i <= 1; i+= 0.01) { console.log(i); console.log(soundtrack.volume); soundtrack.volume = i; await sleep(100); } }El problema es que fadeOut no funciona en absoluto, entra en el bucle for durante 1 iteración y luego existe. Mientras tanto, fadeIn funciona perfectamente. Simplemente no puedo entender. Por cierto, este es mi primer proyecto de pasatiempo de JavaScript.
Es normal que una función regrese cuando llega a un await . Devuelve una promesa. Debe asegurarse de que la persona que llama también espere la resolución de esa promesa, que solo se resolverá cuando la primera función termine todas sus tareas.
Asi que:
async function nextSong() { //^^^^ songIndex = (songIndex + 1) % songs.length; await fadeOut(audio); //^^^^^ await loadSong(songs[songIndex]); await playSong(); await fadeIn(audio); } Asumo aquí que loadSong y playSong también devuelven promesas, por lo que estas llamadas también necesitan el operador await .
Parece que el problema podría provenir de su función nextSong . Está llamando a varias funciones async , cada una de las cuales se ejecuta de forma independiente. Desea que se complete el fadeOut antes de cargar/reproducir la siguiente canción.
Hay dos soluciones a esto. La primera sería usar .then para cargar la siguiente canción después de desvanecer la canción actual:
function nextSong() { songIndex++; if (songIndex > songs.length - 1) { songIndex = 0; } fadeOut(audio).then(() => { loadSong(songs[songIndex]); playSong(); fadeIn(audio); }); } O, alternativamente, puede hacer que la función sea async y await la llamada a la función fadeOut:
async function nextSong() { songIndex++; if (songIndex > songs.length - 1) { songIndex = 0; } await fadeOut(audio); loadSong(songs[songIndex]); playSong(); fadeIn(audio); }Estoy de acuerdo con las respuestas anteriores. También creo que, dado que este es un proyecto, puede crear un reproductor de música con estas características sin usar async/await.
Creé un recorte utilizando las direcciones URL de mp3 de archive.org como etiquetas de audio en HTML, y pude hacer que aparecieran y desaparecieran al saltar canciones.
Otro pensamiento, hay declaraciones de funciones y expresiones. Es importante entender la diferencia. Las declaraciones de función se cargan antes de que se ejecute cualquier código, mientras que las expresiones de función se cargan solo cuando el intérprete llega a esa línea de código.
Expresión de función
alert(foo()); // ERROR! foo wasn't loaded yet var foo = function() { return 5; }Declaración de función
alert(foo()); // Alerts 5. Declarations are loaded before any code can run. function foo() { return 5; }Utilice declaraciones de funciones cuando desee crear una función en el ámbito global y hacer que esté disponible en todo el código. Use expresiones de función para limitar dónde está disponible la función, mantenga su alcance global ligero y mantenga una sintaxis limpia.
Prefiero usar expresiones de función en todo mi código a menos que sea necesaria una declaración de función.
Si desea practicar el uso de async/await, puede ver estas otras preguntas de stackoverflow.