Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在等待async.map()完成后,如何返回推送数组?_Javascript_Promise_Async Await_Axios - Fatal编程技术网

Javascript 在等待async.map()完成后,如何返回推送数组?

Javascript 在等待async.map()完成后,如何返回推送数组?,javascript,promise,async-await,axios,Javascript,Promise,Async Await,Axios,最终结果将存储在下面的位置数组中 const locations = [] 我创建了一个异步函数,它接受一个location参数,locationSearch将使用该参数向googleplaces发出GET请求 const locationSearch = await ( axios.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?query=${location}`, {json: true})

最终结果将存储在下面的位置数组中

const locations = []
我创建了一个异步函数,它接受一个location参数,locationSearch将使用该参数向googleplaces发出GET请求

const locationSearch = await (
    axios.get(`https://maps.googleapis.com/maps/api/place/textsearch/json?query=${location}`, {json: true})
    .then(response => {
        if(response.data.results.length < 1) throw new Error('Unable to find location.')

        return response.data.results
    }).catch(error => {
        return error
    }) 
)
但是,我不确定应该在哪里返回位置,因为locationDetails仅用于将结果映射到位置。已解决的承诺返回如下:

return Promise.all(locationSearch, locationDetails)

我希望这个问题不会让人觉得很傻。此外,任何关于所写代码错误的反馈或指点都将不胜感激

对于async/await,您不需要像.then和.catch这样使用promise API,它是使用promise结构的替代方法。它应该更像这样:

async function getLocationData (location) {
  try {
    const { data } = axios.get(
      `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${location}`,
      { json: true }
    )

    if (data.results) {
      const locationDetails = await Promise.all(
        data.results.map(({ place_id }) =>
          // for each of these, catch any errors and return null so you know you got nothing
          // but it won't kill the entire batch of requests
          axios.get(
            `https://maps.googleapis.com/maps/api/place/details/json?placeid=${id}`,
            { json: true }
          ).catch(() => null)
        )
      )
      return locationDetails.reduce((arr, details) => {
        // only add the data if it exists
        if (Array.isArray(details.result) && details.result.length) {
          const {
            name,
            geometry,
            types,
            photos,
            rating,
            user_ratings_total,
            opening_hours,
            icon,
            formatted_address,
            formatted_phone_number,
            price_level,
            reviews
          } = details

          return [
            ...arr,
            {
              latitude: geometry.location.lat,
              longitude: geometry.location.lng,
              types,
              reviews,
              photos,
              rating,
              user_ratings_total,
              opening_hours,
              icon,
              name,
              location: formatted_address,
              formatted_phone_number,
              price_level
            }
          ]
        }
        // otherwise it's an errored result (null) or no match
        // so return the accumulated array (essentially a filter)
        return arr
      }, [])
    } else {
      throw new Error('Unable to find location')
    }
  } catch (err) {
    return err
  }
}
这里需要注意的主要事情是,一旦任何请求失败,所有请求都将停止。因此,您可以向Promise.all映射中的每个axios调用添加.catch,以防止整个批拒绝。然后,您将得到一个与位置结果数量匹配的数组,现在您将得到失败的结果,因为它们将为null,或者您希望为失败的请求返回的任何内容


此外,在处理错误时保持一致也是一个好主意。要么一直扔,要么一直回来。

解决这个问题的方法非常清晰明了,感谢您指出不同的方法!很高兴我能帮忙!
async function getLocationData (location) {
  try {
    const { data } = axios.get(
      `https://maps.googleapis.com/maps/api/place/textsearch/json?query=${location}`,
      { json: true }
    )

    if (data.results) {
      const locationDetails = await Promise.all(
        data.results.map(({ place_id }) =>
          // for each of these, catch any errors and return null so you know you got nothing
          // but it won't kill the entire batch of requests
          axios.get(
            `https://maps.googleapis.com/maps/api/place/details/json?placeid=${id}`,
            { json: true }
          ).catch(() => null)
        )
      )
      return locationDetails.reduce((arr, details) => {
        // only add the data if it exists
        if (Array.isArray(details.result) && details.result.length) {
          const {
            name,
            geometry,
            types,
            photos,
            rating,
            user_ratings_total,
            opening_hours,
            icon,
            formatted_address,
            formatted_phone_number,
            price_level,
            reviews
          } = details

          return [
            ...arr,
            {
              latitude: geometry.location.lat,
              longitude: geometry.location.lng,
              types,
              reviews,
              photos,
              rating,
              user_ratings_total,
              opening_hours,
              icon,
              name,
              location: formatted_address,
              formatted_phone_number,
              price_level
            }
          ]
        }
        // otherwise it's an errored result (null) or no match
        // so return the accumulated array (essentially a filter)
        return arr
      }, [])
    } else {
      throw new Error('Unable to find location')
    }
  } catch (err) {
    return err
  }
}