在map函数中使用axios时返回一个promise数组?
Posted
技术标签:
【中文标题】在map函数中使用axios时返回一个promise数组?【英文标题】:An array of promises is returned when using axios in map function? 【发布时间】:2021-12-30 09:24:04 【问题描述】:我正在通过这个 dummyAssests 数组进行映射,并希望根据名为 newAssetArray 的 axios 响应创建一个新的对象数组。但是当我 console.log 时 newAssetArray 它只包含一个 Promises 数组......
useEffect(() =>
let newAssetArray = dummyAssets.map(async function (asset)
return await axios
.get(currrentPrice(asset.asset_id))
.then((response) =>
let cp = response.data.market_data.current_price.eur;
let value = Number(cp) * Number(asset.amount);
return ...asset, value: +value ;
)
.catch((error) => console.log(error.response.data.error));
);
setAssets(newAssetArray);
console.log(newAssetArray);
, [dummyAssets]);
控制台:
【问题讨论】:
是的,这是意料之中的。使用Promise.all()
等待所有的承诺解决。 .map()
本身没有承诺意识,因此它不会“等待”其循环的每个单独迭代在进入下一个迭代之前解决。所以,你有调用 N 个async
函数的结果,它们都返回一个承诺作为你的.map()
结果。这就是代码应该如何工作的方式。 await
您正在使用它没有完成任何事情。如果您改用 for
循环(这是可感知的,那么您的循环将被排序。
谢谢。你能举例说明如何使用 Promise.all() 吗?
【参考方案1】:
是的,这是意料之中的。使用Promise.all()
等待所有的承诺解决。 .map()
本身不具备承诺意识,因此它不会“等待”其循环的每个单独迭代解决,然后再进行下一个迭代。所以,你有调用 N 个async
函数的结果,它们都返回一个承诺作为你的.map()
结果。这就是代码应该如何工作的方式。您正在使用它的 await 没有完成任何事情。如果您改用 for 循环(它可以感知承诺,那么您的循环将被排序。
以下是使用Promise.all()
获取结果的方法:
useEffect(() =>
Promise.all(dummyAssets.map(function(asset)
return axios
.get(currrentPrice(asset.asset_id))
.then((response) =>
let cp = response.data.market_data.current_price.eur;
let value = Number(cp) * Number(asset.amount);
return ...asset, value: +value ;
).catch((error) =>
console.log(error.response.data.error)
throw error;
);
)).then(newAssetArray =>
console.log(newAssetArray);
setAssets(newAssetArray);
).catch(err =>
// do something to handle the error here
);
, [dummyAssets]);
或者,您可能会发现这个实现更简单:
useEffect(async () =>
try
const newAssetArray = await Promise.all(dummyAssets.map(async function(asset)
const response = await axios.get(currrentPrice(asset.asset_id));
const cp = response.data.market_data.current_price.eur;
const value = Number(cp) * Number(asset.amount);
return ...asset, value: +value ;
));
console.log(newAssetArray);
setAssets(newAssetArray);
catch (e)
// do something to handle the error here
console.log(e);
, [dummyAssets]);
另外,请注意以下结构:
async function someFunction()
return await axios.get()
没有什么不同,只是:
async someFunction()
return axios.get()
它们都返回一个可以解析为 axios.get()
解析的任何内容的承诺。第一个返回一个承诺,因为它在一个异步函数中,并且所有异步函数在它们遇到第一个await
时都返回一个承诺。第二个返回一个承诺,因为您直接返回 axios.get()
承诺。无论哪种方式,它们都返回一个解决相同问题的承诺。
所以,一般return await fn()
对您没有帮助,而只是return fn()
,不推荐。然后,一旦你停止在那里使用await
,你就不再需要async
来进行.map()
回调。
【讨论】:
以上是关于在map函数中使用axios时返回一个promise数组?的主要内容,如果未能解决你的问题,请参考以下文章
TypeError:使用axios获取数据时language.map不是函数
如何使用带有 (axios/classhooks) 的 map 函数从 API 中读取