繁体   English   中英

异步函数不等待等待获取

[英]async function doesn't wait await fetch

我有一个必须从 Spotify API 验证某些艺术家的函数,但是当我运行它时, 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)
      }
    })
}

这是我调用函数的地方; 我之前调用它,以便它可以填充artists变量:

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
    }    
 

我该如何解决?

你可以使用 Promise.all() 像:

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

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

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

或者

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

一次看一个片段, setArtists确实必须异步并且可能当前应该运行验证(因为验证不是相互依赖的)。

在包含范围内不需要artists全局。 事实上,拥有它会鼓励错误。

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

validateArtist方法混合了异步样式。 在这里,它具有统一的风格和更明确的目标:只是验证并返回艺术家......

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

最后,您的调用者也必须是异步的,并等待setArtists结果...

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
  } 
  // ...

附带说明一下,艺人数组中可能有一些有价值的东西,它们可以通过 Spotify 返回,即您查询的一些超级数据集。 如果您希望保留结果,您可以制定一个策略来选择在 spotify 匹配数组中返回的第一个匹配艺术家......

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM