Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

132
Visualizações
async function doesn't wait await fetch

I have a function that must validate some artist from Spotify API, but when I run it artists[] remains empty because the function is not waiting the fetch, it fills the variable user without having set artists.

let artists = []

function setArtists(input) {
  artists.length = 0
  let parsedInput = input.value.split(",")
  parsedInput.forEach(artist => {
    validateArtist(artist)
  })
}

async function validateArtist(s) {
  let token = localStorage.getItem("Token")
  let url = "https://api.spotify.com/v1/search?type=artist&q=" + s
  console.log(url)
  await fetch(url, {
      "method": "GET",
      "headers": {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        "Authorization": "Bearer " + token,
      }
    })
    .then(response => {
      if (response.status === 401) {
        refreshToken(s)
      }
      return response.json()
    })
    .then(searchedResults => searchedResults.artists.items.length != 0)
    .then(isArtist => {
      if (isArtist) {
        artists.push(s)
      }
    })
}

Here is where I call the function, I call it before so it can fill artists variable.

setArtists(document.getElementById("artistiPreferiti"))
    var user = {
            username: document.getElementById("username").value,
            email: document.getElementById("email").value,
            password: document.getElementById("password").value,
            gustiMusicali: document.getElementById("gustiMusicali").value,
            artistiPreferiti: artists
    }    
 

How can i fix it?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

You can use Promise.all() like:

const artists = ['first', 'second'];

const promises = artists.map(artist => fetch(url+artist));

Promise.all(promises)
.then(response => {
  // handle response
})
.catch(err);

or

const returnedData = await Promise.all(promises).catch(err);

about 4 years ago · Juan Pablo Isaza Relatório

0

Looking at the pieces one at a time, setArtists must indeed by async and should probably run the validation currently (since the validations are not interdependent).

There's no need for the artists global in the containing scope. In fact, having it will encourage errors.

// clarifying... input is a comma-delimited string describing artists
// validate each one with spotify, and return an array of the valid artists
async function setArtists(input) {
  let parsedInput = input.value.split(",")
  let promises = parsedInput.map(validateArtist);
  let results = await Promise.all(promises);  // validate all of them at once
  // return just the valid inputs, not the nulls
  return results.filter(r => r);
}

The validateArtist method mixes async styles. Here it is with uniform style and with a clearer objective: to just validate and return an artist...

// given the params of an artist, lookup on spotify and return a
// a promise that resolves to the input artist if valid, null otherwise
async function validateArtist(s) {
  const token = localStorage.getItem("Token")
  const url = "https://api.spotify.com/v1/search?type=artist&q=" + s
  console.log(url)
  const response = await fetch(url, {
      "method": "GET",
      "headers": {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        "Authorization": "Bearer " + token,
      }
  });
  if (response.status === 401) {
    refreshToken(s)
  }
  const searchedResults = await response.json();
  const isArtist = searchedResults.artists.items.length != 0;
  // notice, no side-effects here, resolve to the input artist or null
  return isArtist ? s : null;
}

Lastly, your caller must be async also, and await the setArtists result...

async function theCaller() {
  // notice - no need for a global. now it's a local here...
  let artists = await setArtists(document.getElementById("artistiPreferiti"))
  var user = {
    username: document.getElementById("username").value,
    email: document.getElementById("email").value,
    password: document.getElementById("password").value,
    gustiMusicali: document.getElementById("gustiMusicali").value,
    artistiPreferiti: artists
  } 
  // ...

As a side note, there might be valuable stuff in the artist array that spotify returns, some super set of the data you queried with. If you'd rather keep the results around, you can make up a policy to pick the first matching artist returned in the array of spotify matches...

// updating the functional comment:
// given the params of an artist, lookup on spotify and return a
// a promise that resolves to the first found artist or null if no matches are found

  .then(searchedResults => {
    let items = searchedResults.artists.items;
    return items.length ? items[0] : null;
  });
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda