映射数组值时使用async等待

时间:2017-09-17 16:14:18

标签: javascript arrays asynchronous async-await

我正在尝试将新的async / await与映射数组值结合使用。 但是我有点困惑,在这种特定情况下应该有await关键字。

关于这个主题还有很多信息。

我正在尝试简单地map() over和在Axios get()请求中使用的值数组,然后返回then()值,该值将被添加到返回的数组中通过map()函数。

这是我现在的代码:

async function get_prices (arrayOfDates, crypto, FIAT) {
  // I tried this way (return value can be found below)
  let arry_of_prices = arrayOfDates.map(async function(date){
    let a = await fetch_data(date, crypto, FIAT)
    return a
  });

  // And this way (return value can be found below)
  let arry_of_prices = await arrayOfDates.map(date => fetch_data(date, crypto, FIAT));
} 

const fetch_data = (timestamp, crypto, FIAT) => {
  axios.get(`https://min-api.cryptocompare.com/data/pricehistorical?fsym=${crypto}&tsyms=${FIAT}&ts=${timestamp}`)
  .then(function (response) {
    return Object.values(response.data).map(key => Object.values(key))[0][0]
  })
  .catch(function (error) {
    console.log(error);
  });
}

let arr = [1468965600, 1469052000, 1469138400,1469484000]

get_prices(arr, "BTC", "USD").then(arr => console.log(arr))

第一次尝试返回了4 resolved个承诺,但值为undefined。 而第二个返回一个带有undefined的数组。

有没有人知道如何构建它,以便map()等待函数解析,然后将值添加到数组中?

1 个答案:

答案 0 :(得分:1)

map对promises一无所知,因此当您使用async回调map时,您将获得一系列承诺,而不是值。如果您希望在所有这些承诺得到解决后能够解决的承诺,您可以使用Promise.all

但是,在您的情况下,您不需要异步函数,因为您在回调中使用fetch_data。您需要修改fetch_data,以便axios.get返回承诺(并删除catch处理程序):

const fetch_data = (timestamp, crypto, FIAT) => {
  return axios.get(`https://min-api.cryptocompare.com/data/pricehistorical?fsym=${crypto}&tsyms=${FIAT}&ts=${timestamp}`)
  .then(function (response) {
    return Object.values(response.data).map(key => Object.values(key))[0][0]
  });
}

(这是承诺的规则之一:如果你要退还承诺,你不会处理它的拒绝[除非你想将它们转换成不同的拒绝,或者你可以有效地将它们转换为分辨率而不是如果你返回承诺,你处理拒绝。)

现在你已经有了一个承诺,所以你在map中使用它(不需要async):

async function get_prices (arrayOfDates, crypto, FIAT) {
  let arr_of_price_promises = arrayOfDates.map(function(date){
    let a = fetch_data(date, crypto, FIAT)
    return a
  });
  return Promise.all(arr_of_price_promises);
}

注意我从await前面删除了fetch_data。我们直接返回fetch_data的承诺,然后等待它们。

或使用箭头功能:

async function get_prices (arrayOfDates, crypto, FIAT) {
  let arr_of_price_promises = arrayOfDates.map(date => fetch_data(date, crypto, FIAT));
  return Promise.all(arr_of_price_promises);
}