簡體   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