Mariel
Mariel

Reputation: 13

Why does an await sleep exits a for loop early?

I try to make a fade in & out effect for a music application when I click the next/previous button; I have this sleep function:

const sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds));

the function when the button is pushed:

function nextSong() {
  songIndex++;
  if (songIndex > songs.length - 1) {
    songIndex = 0;
  }
  fadeOut(audio);
  loadSong(songs[songIndex]);
  playSong();
  fadeIn(audio);
}

and the fading functions

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

The problem is fadeOut doesn't work at all, it goes in the for loop for 1 iteration and then exists. Meanwhile, fadeIn works perfectly. I just can't understand. Btw this is my first javascript hobby project.

Upvotes: 1

Views: 155

Answers (3)

xxkazunarixx
xxkazunarixx

Reputation: 74

I agree with the previous answers. I also think that, given this is a project, you can create a music player with these features without using async/await.

I created a snipped using archive.org mp3 urls as audio tags in HTML, and was able to get them to fade in and out when skipping songs.

One other thought, there are both function declarations and expressions. It is important to understand the difference. Function declarations load before any code is executed while Function expressions load only when the interpreter reaches that line of code.

Function Expression

alert(foo()); // ERROR! foo wasn't loaded yet
var foo = function() { return 5; }

Function Declaration

alert(foo()); // Alerts 5. Declarations are loaded before any code can run.
function foo() { return 5; }

Use function declarations when you want to create a function on the global scope and make it available throughout your code. Use function expressions to limit where the function is available, keep your global scope light, and maintain clean syntax.

I prefer using function expressions throughout my code unless a function declaration is necessary.

If you are wanting to practice using async/await, you could see these other stackoverflow questions.

How and when to use ‘async’ and ‘await’

What is the use case for async/await?

Upvotes: -1

Deanveloper
Deanveloper

Reputation: 95

It looks like the issue might be coming from your nextSong function. You are calling multiple async functions, which are each running independently of each other. You want fadeOut to complete before loading/playing the next song.

There's two solutions to this. The first one would be to use .then to load the next song after fading out the current song:

function nextSong() {
  songIndex++;
  if (songIndex > songs.length - 1) {
    songIndex = 0;
  }

  fadeOut(audio).then(() => {
    loadSong(songs[songIndex]);
    playSong();
    fadeIn(audio);
  });
}

Or, alternatively, you can make the function async and await the fadeOut function call:

async function nextSong() {
  songIndex++;
  if (songIndex > songs.length - 1) {
    songIndex = 0;
  }

  await fadeOut(audio);
  loadSong(songs[songIndex]);
  playSong();
  fadeIn(audio);
}

Upvotes: 0

trincot
trincot

Reputation: 350272

It is normal that a function returns when it gets to an await. It returns a promise. You must make sure that the caller also awaits the resolution of that promise, which will only resolve when the first function finishes all its tasks.

So:

async function nextSong() {
//^^^^
  songIndex = (songIndex + 1) % songs.length;
  await fadeOut(audio);
//^^^^^
  await loadSong(songs[songIndex]);
  await playSong();
  await fadeIn(audio);
}

I am assuming here that loadSong and playSong also return promises, and so these calls also need the await operator.

Upvotes: 2

Related Questions