Javascript 使用Promis.all处理多个api调用,并使用react-redux处理数据
我正在使用react/redux构建一个应用程序,用于管理电子设备的收集(=捐赠)。 在第一阶段,我需要进行2次api调用: 第一个和第二个是捐赠数据和捐赠者数据(在mongodb中作为不同的集合保存),然后将它们合并。此信息显示在捐赠路线中。 操作如下所示:Javascript 使用Promis.all处理多个api调用,并使用react-redux处理数据,javascript,reactjs,redux,es6-promise,Javascript,Reactjs,Redux,Es6 Promise,我正在使用react/redux构建一个应用程序,用于管理电子设备的收集(=捐赠)。 在第一阶段,我需要进行2次api调用: 第一个和第二个是捐赠数据和捐赠者数据(在mongodb中作为不同的集合保存),然后将它们合并。此信息显示在捐赠路线中。 操作如下所示: const basicUrl = 'http://localhost:8000/api'; export const requestDonor_DonationData = () => getDonationData ( `
const basicUrl = 'http://localhost:8000/api';
export const requestDonor_DonationData = () => getDonationData (
`${basicUrl}/donor`,
`${basicUrl}/donation`
);
import {
REQUEST_ENTITIES_PENDING,
REQUEST_ENTITIES_SUCCES,
REQUEST_ENTITIES_FAILED
} from './constants';
export const getDonationData = (urlDonor, urlDonation) => (dispatch) => {
dispatch ( {type: REQUEST_ENTITIES_PENDING} );
Promise.all([
fetch(urlDonor).then(res => res.json()),
fetch(urlDonation).then(res => res.json())
]).then ( ([ donorResult, donationResult]) => donorResult.data.map( (e, i) => Object.assign(e, donationResult.data[i]) ) )
.then( mergedData => dispatch({type: REQUEST_ENTITIES_SUCCES, payload: mergedData }) )
.catch(error => dispatch({type: REQUEST_ENTITIES_FAILED, payload: error}) )
}
getDonationData函数如下所示:
const basicUrl = 'http://localhost:8000/api';
export const requestDonor_DonationData = () => getDonationData (
`${basicUrl}/donor`,
`${basicUrl}/donation`
);
import {
REQUEST_ENTITIES_PENDING,
REQUEST_ENTITIES_SUCCES,
REQUEST_ENTITIES_FAILED
} from './constants';
export const getDonationData = (urlDonor, urlDonation) => (dispatch) => {
dispatch ( {type: REQUEST_ENTITIES_PENDING} );
Promise.all([
fetch(urlDonor).then(res => res.json()),
fetch(urlDonation).then(res => res.json())
]).then ( ([ donorResult, donationResult]) => donorResult.data.map( (e, i) => Object.assign(e, donationResult.data[i]) ) )
.then( mergedData => dispatch({type: REQUEST_ENTITIES_SUCCES, payload: mergedData }) )
.catch(error => dispatch({type: REQUEST_ENTITIES_FAILED, payload: error}) )
}
那很好
在第二阶段,当一项捐赠被偷看时,它就变成了一个设备(不是一个完美的词…),这意味着现在它正在等待检查。此信息显示在设备路线中。
设备数据包含捐赠ID和状态(与捐赠状态不同)。
现在我想做一些类似的事情:
export const requestEquipmentData = () => getEquipmentData (
[
`${basicUrl}/donor`,
`${basicUrl}/donation`,
`${basicUrl}/equipment`
]
);
export const getEquipmentData = (urls) => (dispatch) => {
dispatch ( {type: REQUEST_ENTITIES_PENDING} );
try {
const [ donorResult, donationResult, equipmentResult ] = Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
const donationInfo = donorResult.data.map( (e, i) => Object.assign(e, donationResult.data[i]) );
const filteredDonation = donationInfo.filter(item =>item.status==='DONE');
const equipment = filteredDonation.map( (donation,i) => {
let obj = donation;
obj.id = equipmentResult.data[i].id;
obj.status = equipmentResult.data[i].status;
return obj;
})
dispatch({type: REQUEST_ENTITIES_SUCCES, payload: equipment });
} catch (error) {
dispatch({type: REQUEST_ENTITIES_FAILED, payload: error})
}
}
但我做错了什么,这就是错误:
type: "REQUEST_ENTITIES_FAILED", payload: TypeError: undefined is not a function
我将非常感激对
Promise.all()
结果的任何帮助。all()是一个Promise
,解析为结果数组。它本身不是数组,因此不能像这样对其进行分解
您可以使用与第一个示例中相同的.then()
方法:
export const getEquipmentData = (urls) => (dispatch) => {
dispatch({ type: REQUEST_ENTITIES_PENDING });
Promise.all(urls.map(async function (url) {
const response = await fetch(url);
return response.json();
})).then(([donorResult, donationResult, equipmentResult]) => {
const donationInfo = donorResult.data.map((e, i) => Object.assign(e, donationResult.data[i]));
const filteredDonation = donationInfo.filter(item => item.status === 'DONE');
const equipment = filteredDonation.map((donation, i) => {
let obj = donation;
obj.id = equipmentResult.data[i].id;
obj.status = equipmentResult.data[i].status;
return obj;
})
dispatch({ type: REQUEST_ENTITIES_SUCCES, payload: equipment });
}).catch(error) {
dispatch({ type: REQUEST_ENTITIES_FAILED, payload: error })
}
}
或者可以使用async
/await
语法。有关解决一系列承诺的一般性讨论
export const getEquipmentData = (urls) => async (dispatch) => {
dispatch ( {type: REQUEST_ENTITIES_PENDING} );
try {
const [ donorResult, donationResult, equipmentResult ] = await Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
const donationInfo = donorResult.data.map( (e, i) => Object.assign(e, donationResult.data[i]) );
const filteredDonation = donationInfo.filter(item =>item.status==='DONE');
const equipment = filteredDonation.map( (donation,i) => {
let obj = donation;
obj.id = equipmentResult.data[i].id;
obj.status = equipmentResult.data[i].status;
return obj;
})
dispatch({type: REQUEST_ENTITIES_SUCCES, payload: equipment });
} catch (error) {
dispatch({type: REQUEST_ENTITIES_FAILED, payload: error})
}
}
我认为你在这方面的一般做法不好。你应该阅读上的指南。似乎您的API正在返回规范化数据,然后您正在通过组合来自多个端点的数据来“非规范化”数据。这是Promise的结果。all()
是一个Promise
,解析为结果数组。它本身不是数组,因此不能像这样对其进行分解
您可以使用与第一个示例中相同的.then()
方法:
export const getEquipmentData = (urls) => (dispatch) => {
dispatch({ type: REQUEST_ENTITIES_PENDING });
Promise.all(urls.map(async function (url) {
const response = await fetch(url);
return response.json();
})).then(([donorResult, donationResult, equipmentResult]) => {
const donationInfo = donorResult.data.map((e, i) => Object.assign(e, donationResult.data[i]));
const filteredDonation = donationInfo.filter(item => item.status === 'DONE');
const equipment = filteredDonation.map((donation, i) => {
let obj = donation;
obj.id = equipmentResult.data[i].id;
obj.status = equipmentResult.data[i].status;
return obj;
})
dispatch({ type: REQUEST_ENTITIES_SUCCES, payload: equipment });
}).catch(error) {
dispatch({ type: REQUEST_ENTITIES_FAILED, payload: error })
}
}
或者可以使用async
/await
语法。有关解决一系列承诺的一般性讨论
export const getEquipmentData = (urls) => async (dispatch) => {
dispatch ( {type: REQUEST_ENTITIES_PENDING} );
try {
const [ donorResult, donationResult, equipmentResult ] = await Promise.all(urls.map(async function(url) {
const response = await fetch(url);
return response.json();
}));
const donationInfo = donorResult.data.map( (e, i) => Object.assign(e, donationResult.data[i]) );
const filteredDonation = donationInfo.filter(item =>item.status==='DONE');
const equipment = filteredDonation.map( (donation,i) => {
let obj = donation;
obj.id = equipmentResult.data[i].id;
obj.status = equipmentResult.data[i].status;
return obj;
})
dispatch({type: REQUEST_ENTITIES_SUCCES, payload: equipment });
} catch (error) {
dispatch({type: REQUEST_ENTITIES_FAILED, payload: error})
}
}
我认为你在这方面的一般做法不好。你应该阅读上的指南。似乎您的API正在返回规范化数据,然后您正在通过组合来自多个端点的数据来“非规范化”数据。您可能正在调用文件中的dispatch
,但您无权访问该文件。尝试控制台记录并查看。您可能正在调用您无权访问的文件中的dispatch
。试着把它记录下来看看。非常感谢!在第二种方法中,我错过了异步等待,而在第一种方法中,我没有意识到URL:string[]。你对api的看法是对的-我没有决定这样设计它们,我被告知这样设计的原因是为了生成报告,无论如何我会探索它,再次感谢你提供的详细答案!!哦那url:string[]
是个意外。我用Typescript写代码,但忘了删除类型!好的,谢谢你说清楚:)非常感谢!在第二种方法中,我错过了异步等待,而在第一种方法中,我没有意识到URL:string[]。你对api的看法是对的-我没有决定这样设计它们,我被告知这样设计的原因是为了生成报告,无论如何我会探索它,再次感谢你提供的详细答案!!哦那url:string[]
是个意外。我用Typescript写代码,但忘了删除类型!好的,谢谢你澄清:)