[英]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.