当promise.all解析时,如何过滤处于两种不同状态的数据



我发送了两个请求来获取

1-我的服务2-管理服务

当我得到响应时;myService,admin";。

现在是包含我的服务的管理服务。所以我想过滤我在管理服务中的服务是否从数组中删除管理服务。

所以我尝试使用new Set,但不起作用,也许我错过了

另一个问题是,我使用Promise.all来等待两个请求,但当我在那里记录状态时,我得到了初始状态"空">

数据样本";我的服务和管理;

[
//my service
{
"id": 1,
"img": ".....",
"name": "service 1"
},
{
"id": 2,
"img": ".....",
"name": "service 2"
},
{
"id": 3,
"img": ".....",
"name": "service 3"
},
//admin service
{
"id": 1,
"img": ".....",
"name": "service 1"
},
]

代码段

const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
Api.post('/admin/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
setAdminServices(serviceModified);
})
.catch((err) => console.log('err', err));
};
const getMyServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
Api.post('/vendor/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
setMyServices(serviceModified);
setSelectedService(serviceModified); // for checkbox
})
.catch((err) => console.log('err', err));
};
Promise.all([getMyServices(), getAdminServices()]).then(() => {
let allServices = [...myServices, ...adminServices]; // log empty!
let uniq = [...new Set(allServices)];
console.log(myServices);
console.log('filtered', uniq);
console.log('here i want to filter the data', allServices);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

UI
<FlatList
data={allService}
keyExtractor={(item, index) => String(index)}
renderItem={renderMyServices}
/>

首先,您应该返回来自getMyServicesgetAdminServices的承诺。

此外,在react中设置状态是异步的。因此,myServicesadminServices的更新不能保证在您尝试使用它们时得到反映。我建议您返回承诺的结果,并使用这些值而不是状态。

示例:

const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/admin/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
return serviceModified;
})
.catch((err) => console.log('err', err));
};
const getMyServices = () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/vendor/service', {}, {headers})
.then((res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
return serviceModified;
})
.catch((err) => console.log('err', err));
};
Promise.all([getMyServices(), getAdminServices()]).then(([myServices, adminServices]) => {
// set state and do stuff
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

我认为您错误地使用了promises.all

理想情况下,promises.all只能在所有函数都返回您承诺的情况下等待,但在您的情况下,您正在返回undefined

因此,即使在API调用响应之前,Promises.all也将完成执行,并且then也被执行。

您可以将代码重组为如下所示,(尽管如此,我还是看到了很大的重构空间(。


const [myServices, setMyServices] = useState([]);
const [adminServices, setAdminServices] = useState([]);
const [allService, setAllService] = useState([]);
useEffect(() => {
const getAdminServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/admin/service', {}, {headers});
};
const setMyServices = (res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('mine', serviceModified);
setMyServices(serviceModified);
setSelectedService(serviceModified); // for checkbox
return serviceModified;
}

const setAdminServices = (res) => {
let {services} = res.data;
let serviceModified = [];
services.map((service) => {
serviceModified.push({
id: service.id,
name: service.service_name,
img: DOMAIN_URL + service.images_show[0]?.image,
});
});
console.log('admin', serviceModified);
setAdminServices(serviceModified);
return serviceModified;
}  

const getMyServices = async () => {
let AuthStr = `Bearer ${token}`;
const headers = {
Authorization: AuthStr,
Accept: 'application/json',
};
return Api.post('/vendor/service', {}, {headers});
};
Promise.all([getMyServices(), getAdminServices()]).then((data) => {
console.log(data); // will have [myServiceResponse, adminServiceReponse];
const myServices = setMyServices(data[0]);
const adminServices = setAdminServices(data[1]);
let allServices = [...myServices, ...adminServices]; // log empty!
// set doesn't work this way, use `uniq` utility function from `lodash` or develop a custom one if required.
let uniq = [...new Set(allServices)];
console.log(myServices);
console.log('filtered', uniq);
console.log('here i want to filter the data', allServices);
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

最新更新