【问题标题】:async function doesn't wait await fetch异步函数不等待等待获取
【发布时间】:2022-07-06 23:35:26
【问题描述】:

我有一个必须验证来自 Spotify API 的艺术家的函数,但是当我运行它时,艺术家 [] 仍然为空,因为该函数没有等待提取,它填充变量用户而没有设置艺术家。

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

这里是我调用函数的地方,我之前调用它是为了填充艺术家变量。

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
    }    
 

我该如何解决?

【问题讨论】:

  • forEach 与 async await 永远不会像您期望的那样工作。使用常规 for 循环
  • 您的setArtist() 函数也需要为async,并且需要await 验证函数调用。 awaitsetArtist() 的调用将不得不进行其他操作,因为只有在满足承诺之后,数组才会按照您的预期进行更新。

标签: javascript asynchronous async-await fetch-api


【解决方案1】:

带有 async await 的 forEach 永远不会像您期望的那样工作。使用常规 for 循环

  • JaromandaX

我们的 setArtist() 函数也需要异步,它需要等待验证函数调用。其他的东西将不得不等待调用它,因为只有在 promise 得到满足之后,数组才会按照你的预期进行更新。

  • @Pointy
let artists = []

function async setArtists(input) {
  artists.length = 0
  let parsedInput = input.value.split(",")
  for(let i = 0; i < artists.length; i++){
     await validateArtist(artists[i]);
  }
}

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

【讨论】:

  • 这仍然不能解决问题。主要问题是他们在调用setArtists() 后立即使用artists 数组。当然,这将设置参考,但我猜他们可能不想创建 user 变量,直到 artists 完全设置。我会改变整个事情,创建一个纯异步函数,它总是返回一个经过验证的艺术家的新数组,然后await 该结果将在某些user 上下文中使用。如果没有看到其余的代码,如果没有其他重要的重构,这可能是不可能的。
猜你喜欢
  • 2023-03-13
  • 2019-06-16
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 2016-07-07
  • 2016-03-25
  • 2017-10-09
相关资源
最近更新 更多