问题描述
背景
我正在构建一个 React-Redux 应用程序,它必须处理一些对私有 API 的 axios 调用.所述 API 不在我的控制之下,我无法修改任何内容.其中一个 axios 请求由一个函数执行,我们称之为getData".这个请求使用 POST 作为它的方法并且需要一个参数category",它一次只接受一个值.有时我需要一次执行三个请求,我打算以编程方式执行此操作,而不是为每个可能的请求硬编码一个请求,因为可用类别的数量很多.
我打算构建什么
一个执行请求的函数,它接受两个参数,一个是令牌,另一个是作为类别"传递的可能值数组.参数.该函数应该为数组中的每个值运行一次,并返回一个包含所有产品"的对象数组.从后端带来.
我已经构建的
export const getData = (tk, values) =>价值观.map(值=>apiInstance.request({网址:ENDPOINTS.ENDPOINT,方法:'POST',数据:qs.stringify({令牌:令牌,类别:价值,}),}),).then(响应 => {返回 response.data;}).catch(错误=> {返回 Promise.reject(error.message);});
以上是实际请求,接下来是 redux 操作:
export const actionTypes = keyMirror({RETRIEVE_REQUEST:空,RETRIEVE_SUCCESS:空,RETRIEVE_FAILURE:空,});const actionCreators = {请求:createAction(actionTypes.RETRIEVE_REQUEST),成功:createAction(actionTypes.RETRIEVE_SUCCESS),失败:createAction(actionTypes.RETRIEVEO_FAILURE),};export constretrieveData = (tk, values) =>调度 =>{调度(actionCreators.request());Promise.all(getData(tk, values)).then(data => dispatch(actionCreators.success(data))).catch(error => dispatch(actionCreators.failure(error)));};
还有减速器:
export const initialState = {加载:假,数据: [],错误:空,};const 动作映射 = {[actionTypes.RETRIEVE_REQUEST]:状态 =>({...状态,加载:真实,}),[actionTypes.RETRIEVE_SUCCESS]:(状态,动作)=>({...状态,加载:假,数据:action.payload,}),[actionTypes.RETRIEVE_FAILURE]:(状态,动作)=>({...状态,加载公共:假,错误:action.payload,}),};导出默认值(状态 = 初始状态,动作)=>{const actionHandler = actionsMap[action.type];如果(!actionHandler){返回状态;}返回 actionHandler(state, action);};
请注意,所有这些都在单独的文件中.
问题
我收到错误消息 undefined is not a function (near '...}).then(function (response)...')
这指向 values.map((值) =>
问题
据我所知,.map 可以接收一个像这样的短箭头函数作为它的第一个参数.Values 是一个字符串数组,所以理论上它应该可以工作.我错过了什么?
问题在于您将 values
映射到 Promise 列表.
但是,在您的情况下,.then()
不能在列表 ([Promise, Promise, ...]
) 上调用.事实上, .then
将是 undefined
这正是错误消息告诉你的.
相反,尝试将 values.map(...)
包装在 Promise.all(...)
中.这将在调用 .then(...)
之前等待所有 promise 得到解决.
请记住,传递给 .then(...)
的 response
实际上也是一个列表!
所以你想做这样的事情:
Promise.all(价值观.map(值=>apiInstance.request({网址:ENDPOINTS.ENDPOINT,方法:'POST',数据:qs.stringify({令牌:令牌,类别:价值,}),}),)).then(响应 => {//响应是一个列表!返回 response.map(response => response.data);}).catch(错误=> {返回 Promise.reject(error.message);});
Background
I'm building a React-Redux application which, amongst other things, has to handle some axios calls to a private API. Said API is not under my control, and I cannot modify anything. One of the axios requests is performed by a function, let's call it "getData". This request uses POST as its method and requires a parameter "category", this accepts only one value at a time. Thing is sometimes I need to perform say three requests at a time and I intend to do so programatically rather than hardcoding a request for each possible request, as the number of available categories is high.
What I intent to build
A function which performs a request, taking in two parameters, one is a token, the other one is an array of possible values to be passed as the "category" param. The function should run once per value in the array and return a single array of objects which holds all of the "products" brought over from the backend.
What I've built already
export const getData = (tk, values) =>
values
.map(value =>
apiInstance.request({
url: ENDPOINTS.ENDPOINT,
method: 'POST',
data: qs.stringify({
token: token,
category: value,
}),
}),
)
.then(response => {
return response.data;
})
.catch(error => {
return Promise.reject(error.message);
});
Above is the actual request and next is the redux action:
export const actionTypes = keyMirror({
RETRIEVE_REQUEST: null,
RETRIEVE_SUCCESS: null,
RETRIEVE_FAILURE: null,
});
const actionCreators = {
request: createAction(actionTypes.RETRIEVE_REQUEST),
success: createAction(actionTypes.RETRIEVE_SUCCESS),
failure: createAction(actionTypes.RETRIEVEO_FAILURE),
};
export const retrieveData = (tk, values) => dispatch => {
dispatch(actionCreators.request());
Promise.all(getData(tk, values))
.then(data => dispatch(actionCreators.success(data)))
.catch(error => dispatch(actionCreators.failure(error)));
};
And the reducer:
export const initialState = {
loading: false,
data: [],
error: null,
};
const actionsMap = {
[actionTypes.RETRIEVE_REQUEST]: state => ({
...state,
loading: true,
}),
[actionTypes.RETRIEVE_SUCCESS]: (state, action) => ({
...state,
loading: false,
data: action.payload,
}),
[actionTypes.RETRIEVE_FAILURE]: (state, action) => ({
...state,
loadingPublic: false,
error: action.payload,
}),
};
export default (state = initialState, action) => {
const actionHandler = actionsMap[action.type];
if (!actionHandler) {
return state;
}
return actionHandler(state, action);
};
Problem
I'm getting the error message undefined is not a function (near '...}).then(function (response)...')
and this points to values.map((value) =>
Question
As far as I understand, .map can recieve a short-arrow function such as this as its first parameter. Values is an array of strings, so it should work in theory. What am I missing?
The problem is that you map your values
to a list of Promises.
However, .then()
is not callable on a list ([Promise, Promise, ...]
) in your case. In fact, .then
will be undefined
which is exactly what the error message tells you.
Instead, try to wrap values.map(...)
in a Promise.all(...)
.This will wait for all promises to resolve before calling .then(...)
.
Keep in mind that the response
passed to .then(...)
will actually also be a list!
So you want to do something like this:
Promise.all(
values
.map(value =>
apiInstance.request({
url: ENDPOINTS.ENDPOINT,
method: 'POST',
data: qs.stringify({
token: token,
category: value,
}),
}),
)
)
.then(responses => {
// responses is a list!
return responses.map(response => response.data);
})
.catch(error => {
return Promise.reject(error.message);
});
这篇关于无法执行 .map whithin 功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!