嵌套的 For 循环不适用于 Redux Thunk
Nested For Loop not Working With Redux Thunk
我对 redux thunk 的流程有疑问。
在动作创建器中,我首先创建一个图像对象并从数据库中获取 image_id
。
我有一个名为 clients
的变量,它是所有需要图像 ID 的客户端 ID 的列表。 [1,2,3,4,5]
我通过一个 for 循环,使用 axios.get 获取客户端,然后将新的 image_id 添加到客户端字段的图像列表中。
然后我将新的更改放入字段中的客户端,client_images
。
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
console.log("GETTING NEW CLIENT", currRow)
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}
});
}
}
我的问题出在这里:
整个 for 循环在我调用
之前完成
axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
在我的控制台中,这是输出
如您所见,添加新客户端图像仅在 for 循环完成后调用。我需要在 for 循环中调用 "Adding New Client Images" 以便可以调用另一个 axios 函数,而不是将其调用 5 次给 id 为 5 的客户端。
有没有办法让 for 循环在 redux thunk 中工作?
啊这个一开始总是很棘手。对数组使用 promises 时,请使用 array.map
而不是 for 循环。所以尝试改变这个:
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}
为此:
return Promise.all(clients.map(function(currRow){
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}));
这将确保所有承诺都有自己的范围。
所以最终结果是这样的:
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
return Promise.all(clients.map(function(currRow){
console.log("GETTING NEW CLIENT", currRow)
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
return axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}));
});
}
}
我对 redux thunk 的流程有疑问。
在动作创建器中,我首先创建一个图像对象并从数据库中获取 image_id
。
我有一个名为 clients
的变量,它是所有需要图像 ID 的客户端 ID 的列表。 [1,2,3,4,5]
我通过一个 for 循环,使用 axios.get 获取客户端,然后将新的 image_id 添加到客户端字段的图像列表中。
然后我将新的更改放入字段中的客户端,client_images
。
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
console.log("GETTING NEW CLIENT", currRow)
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}
});
}
}
我的问题出在这里: 整个 for 循环在我调用
之前完成axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
在我的控制台中,这是输出
如您所见,添加新客户端图像仅在 for 循环完成后调用。我需要在 for 循环中调用 "Adding New Client Images" 以便可以调用另一个 axios 函数,而不是将其调用 5 次给 id 为 5 的客户端。
有没有办法让 for 循环在 redux thunk 中工作?
啊这个一开始总是很棘手。对数组使用 promises 时,请使用 array.map
而不是 for 循环。所以尝试改变这个:
for (var i = 0; i < clients.length; i++) {
var currRow = clients[i];
axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}
为此:
return Promise.all(clients.map(function(currRow){
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
// ...
}));
这将确保所有承诺都有自己的范围。
所以最终结果是这样的:
export function addNewClient(imageData, clients) {
return function(dispatch) {
axios.post(`${API_URL}/media`, fileData, { withCredentials: true, headers: { 'Content-Type': 'multipart/form-data' } })
.then(response => {
var image_id = response.data.id;
//go through each client to get current background list
return Promise.all(clients.map(function(currRow){
console.log("GETTING NEW CLIENT", currRow)
return axios.get(`${API_URL}/clients/${currRow}`, { withCredentials: true })
.then(response => {
var currImages = response.data.client_images;
var clientImages = [...currImages, image_id];
console.log("ADDING NEW CLIENT IMAGE IDs", currRow);
return axios.put(`${API_URL}/clients/${currRow}`, {client_images:clientImages}, { withCredentials: true })
})
.catch(() => {
console.log("Can't set image list to clients");
});
}));
});
}
}