【问题标题】:Handling multiple responses from Promises React Native处理来自 Promises React Native 的多个响应
【发布时间】:2020-05-08 12:30:30
【问题描述】:

我有一些返回 Promise 响应的函数。我现在正试图抓住所有这些并将所有数据发送到后端。但是,我不知道如何抓住它们。我有这样的:

   componentDidMount() {
    Promise.all([
        this.getFunction1Data(ONEDAYINTERVAL), //returns an array of objects
        this.getFunction2Data(ONEDAYINTERVAL),
        this.getFunction3Data(ONEDAYINTERVAL),

    ]).then(([response1, response2, response3]) => {
        this.sendDataToServer(response3);
        // do stuff with your data
    }).catch(e => console.error);

}

但这里的问题是,不知何故,它们都是混合的。

示例:有时 reponse2 包含来自所有三个函数的数据,有时 response3 包含所有需要的数据,而 response2 缺少一些对象。我将如何解决这个问题?是否应该有一些函数可以从所有响应中形成一个数组(检查元素是否存在)还是有办法解决? 只是为了仔细检查,我在这里添加了一个函数示例(其他函数相同):

 getFunction1Data(dateFrom) {

    return new Promise((resolve) => {
        AppleKit.initKit(KitPermissions.uploadBasicKitData(), (err, results) => {
            if (err) {
                return;
            }

            AppleKit.getSamples(dateFrom, (err, results) => {
                if (err) {
                    return resolve([]);
                }
                const newData = results.map(item => {
                    return { ...item, name: "Item1" };
                });
                const allData = [...this.state.ActivityItem, ...newData];
                this.setState({ ActivityItem: allData });
                resolve(allData);
            });
        })
    })
}

更新 第二个功能:

  getFucntion2Data(dateFrom) {

    return new Promise((resolve) => {
        AppleKit.initKit(KitPermissions.uploadBasicKitData(), (err, results) => {
            if (err) {
                return;
            }

            AppleHealthKit.getStepsSample(datefrom, (err, results) => {
                if (err) {
                    return resolve([]);
                }
                const newData = results.map(item => {
                    return { ...item, name: "StepsSample" };
                });
                this.setState(({ActivityItem}) => {
                    ActivityItem = [...ActivityItem, ...newData];
                    resolve(ActivityItem);
                    return { newData }
                });
            });
        })
    })
}

【问题讨论】:

    标签: javascript reactjs react-native asynchronous promise


    【解决方案1】:

    主要问题在getFunction1Data

     const allData = [...this.state.ActivityItem, ...newData];
     this.setState({ ActivityItem: allData });
    

    您正在根据现有状态设置状态。每当您这样做时,您都需要使用setState 的回调形式,而不是直接将状态传递给的形式。原因是 state updates may be asynchronous 和当您在渲染之间进行多次更改时被“批处理”。因此,当您构建要提供给 setState 的新状态时,this.state.ActivityItem 可能已过期。

    要使用回调表单,请不要有allData,然后:

     this.setState(({ActivityItem}) => {
         ActivityItem = [...ActivityItem, ...newData];
         resolve(ActivityItem);
         return { ActivityItem }
     });
    

    单独的问题是,您每次调用 getFunction1Data 都会返回(通过承诺)所有收集的数据,而不仅仅是该调用收集的数据。我并不完全清楚你想做什么,但我倾向于让getFunction1Data 只返回它收集的数据 (newData),而不是所有数据,或者修改它以便它得到所有你想得到的信息,而不是三分之一,所以你可以调用一次。

    【讨论】:

    • 哇,非常感谢您的回复。我终于明白了,当我只返回 newData 时,所有的响应都开始成为我所需要的。请再问一个问题,您能建议我如何将这三个功能合二为一吗?它们之间的唯一区别在于不同的方法调用(而不是 getSamples)。我可以用它更新问题。
    • 我已经尝试了几种方法来做到这一点,但不知道在这种情况下我应该如何解析/返回数据
    • @VladDemyan - 抱歉,我错过了它们是不同的功能。 :-) 所以唯一的区别是AppleKit.getSamplesAppleHealthKit.getStepsSample 与第三个使用什么?您可以将它们作为参数传递:getFunctionData(AppleKit.getSamples, ONEDAYINTERVAL) 然后function getFunctionData(fn, dateFrom) 并在函数中使用fn。如果因为thisgetSamplesgetStepsSample 期间出现错误,您可以将bind 添加到调用中:getFunctionData(AppleKit.getSamples.bind(AppleKit), ONEDAYINTERVAL)
    • 工作正常,感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 2018-08-11
    • 2021-06-05
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多