Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.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 使用Promis.all处理多个api调用,并使用react-redux处理数据_Javascript_Reactjs_Redux_Es6 Promise - Fatal编程技术网

Javascript 使用Promis.all处理多个api调用,并使用react-redux处理数据

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 ( `

我正在使用react/redux构建一个应用程序,用于管理电子设备的收集(=捐赠)。 在第一阶段,我需要进行2次api调用: 第一个和第二个是捐赠数据和捐赠者数据(在mongodb中作为不同的集合保存),然后将它们合并。此信息显示在捐赠路线中。 操作如下所示:

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和状态(与捐赠状态不同)。 现在我想做一些类似的事情:

  • 进行3次api调用(获取捐赠者、捐赠和设备数据)

  • 将捐赠者与其捐赠数据合并

  • 过滤合并的 已窥视的捐赠数据(status='DONE')

  • 创建一个新的json,它接受合并的数据并替换ID和 捐赠状态以及设备的ID和状态

  • 我试过了 使用第一种方法(仅使用Promise.all)实现这一点,但发现 使用多个“.然后”

    这就是我所尝试的: 行动-

    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写代码,但忘了删除类型!好的,谢谢你澄清:)