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