Javascript 在React中同时使用多个异步函数时使用标志是否是一种良好的做法?
我正在处理一个React项目,我重用了fetchAPIcall操作,因为我进行了3次不同的初始API调用,而且,我还计划使用更多来添加和编辑我的项。 因此,为了控制API调用的正确顺序,我尝试在最后使用一个标志,即组件的状态。 由于我使用了许多API调用,为了向收藏夹中添加一些项目,并通过“like”按钮快速删除,我想知道使用许多异步函数或API调用时的最佳实践是什么? 我只能想到1)使用标志,2)让API调用操作对每一个单独,但在我的例子中,这将是大量的代码(get user)(get,add,delete FavList)(get Items)(add,edit remove Item)。 顺便说一句,API是我的,用rails制作的 以下是我的问题的主要代码和文件: 这是从我的GetItemsNFavlist组件,这是我加载items和favList项的所有信息的地方。我把它做成了一个我调用的组件,因为我认为这是一个好主意,所以当我将一个项目添加到收藏夹列表时,我可以调用这个组件来更新我的收藏夹列表(但是“更新”部分还没有很好地工作,我不得不回到用户那里,再回到Fav列表中查看更新,甚至注销,再登录查看更改)。 在这里,我调用操作“fetchAPIcall”,并使用“fetchCall”存储对象检查状态和响应数据。在这里,我还进行了两次API调用,1)获取所有项目,2)获取用户的FavoritesList:Javascript 在React中同时使用多个异步函数时使用标志是否是一种良好的做法?,javascript,node.js,reactjs,asynchronous,react-redux,Javascript,Node.js,Reactjs,Asynchronous,React Redux,我正在处理一个React项目,我重用了fetchAPIcall操作,因为我进行了3次不同的初始API调用,而且,我还计划使用更多来添加和编辑我的项。 因此,为了控制API调用的正确顺序,我尝试在最后使用一个标志,即组件的状态。 由于我使用了许多API调用,为了向收藏夹中添加一些项目,并通过“like”按钮快速删除,我想知道使用许多异步函数或API调用时的最佳实践是什么? 我只能想到1)使用标志,2)让API调用操作对每一个单独,但在我的例子中,这将是大量的代码(get user)(get,add
import React, { useEffect, useState } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import PropTypes from 'prop-types';
import * as MyActions from '../actions';
const GetItemsNFavlist = props => {
const {
actions, items, fetchCall, favList, user,
} = props;
const [apiFlag, setApiFlag] = useState({ itm: false, fvl: false });
const itemsUrl = 'https://findmyitem-api.herokuapp.com/items';
const favListUrl = `https://findmyitem-api.herokuapp.com/users/${user.id}/favorites_lists`;
useEffect(() => { // #1
if (!apiFlag.itm && !apiFlag.fvl) actions.fetchAPIcall(itemsUrl, 'get', {});
}, []);
useEffect(() => {
if (!fetchCall.apiData && items[0]) {
actions.fetchAPIcall(favListUrl, 'get', {});
setApiFlag({ itm: true, fvl: false });
}
}, [items]);
useEffect(() => {
if (fetchCall.apiData && !items[0] && !favList[0]) {
actions.setItems(fetchCall.apiData);
actions.fetchAPIreset();
}
if (apiFlag.itm && fetchCall.apiData && !favList[0]) actions.setFavList(fetchCall.apiData);
});
useEffect(() => {
if (favList[0]) {
actions.fetchAPIreset();
setApiFlag({ itm: true, fvl: true });
}
}, [favList]);
return (<> </>);
};
GetItemsNFavlist.propTypes = {
user: PropTypes.objectOf(PropTypes.any).isRequired,
actions: PropTypes.objectOf(PropTypes.any).isRequired,
items: PropTypes.arrayOf(PropTypes.any).isRequired,
favList: PropTypes.arrayOf(PropTypes.any).isRequired,
fetchCall: PropTypes.objectOf(PropTypes.any).isRequired,
};
const mapStateToProps = ({
user, items, fetchCall, favList,
}) => ({
user, items, fetchCall, favList,
});
function mapActionsToProps(dispatch) {
return {
actions: bindActionCreators({ ...MyActions }, dispatch),
};
}
export default connect(mapStateToProps, mapActionsToProps)(GetItemsNFavlist);
以防万一,这是指向我的回购的链接:
提前谢谢!!
致以最诚挚的问候你认为有人有时间读这些吗?“使用旗子是一种好的做法”很少。一次可能只有一面旗帜,但有很多旗帜意味着很难维持。“…async…”否。Flags+async表示您做错了。“当使用许多异步函数或API调用时,最佳做法是什么?”1。使用
wait
将代码视为同步2。使用promise API来正确排序。3.适当地使用这两种方法。4.提升异步操作并组合它们以管理其效果。这是最佳实践。将外部信息添加到进程中是错误的。看起来您保留这些标志只是为了跟踪是否从服务器加载了内容;为什么不直接检查状态变量呢?还有,包装api调用的一秒钟超时是怎么回事?@VLAZ,非常感谢你的回答。我将尝试在代码中为每个操作实现wait。
import axios from 'axios';
const addUsername = username => ({
type: 'SET_NAME',
username,
});
const setUserInfo = user => ({
type: 'SET_USER',
user,
});
const setItems = items => ({
type: 'SET_ITEMS',
items,
});
const setFavList = favList => ({
type: 'SET_FAVLIST',
favList,
});
const fetchAPIbegin = callHeader => ({
type: 'FETCH_API_BEGIN',
callHeader,
});
const fetchAPIsuccess = payload => ({
type: 'FETCH_API_SUCCESS',
payload,
});
const fetchAPIfailure = error => ({
type: 'FETCH_API_FAILURE',
payload: error,
});
const fetchAPIsuccesResp = payload => ({
type: 'FETCH_API_SUCCESS_RESP',
payload,
});
function handleErrors(response) {
if (!response.ok && response.error) { throw Error(JSON.stringify(response)); }
return response;
}
function fetchAPIcall(url, restAct, options) {
return dispatch => {
dispatch(fetchAPIbegin(url, options));
setTimeout(() => axios[restAct](url, options)
.then(handleErrors)
.then(rsp => {
dispatch(fetchAPIsuccesResp(rsp));
return rsp;
})
.then(resp => resp.data)
.then(jsonResp => dispatch(fetchAPIsuccess(jsonResp)))
.catch(err => dispatch(fetchAPIfailure(`${err}`))), 1000);
};
}
const fetchAPIreset = () => ({ type: 'FETCH_API_RESET' });
export {
addUsername,
setUserInfo,
setItems,
setFavList,
fetchAPIcall,
fetchAPIbegin,
fetchAPIsuccess,
fetchAPIfailure,
fetchAPIreset,
fetchAPIsuccesResp,
};