依次执行三个fetch请求
Executing three fetch requests one after the other
我必须一个接一个地执行三个获取请求。也就是说,假设我的三个获取请求是:
const A = (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
const B = (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
const C= (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
首先应该执行"A",然后在A完成时执行B,然后在B完成时执行C。一旦A,B,C完成,我想执行一个函数
doSomething = () => {
//do something after A, B, C are executed
}
我是 "promises" 的新手。有人可以指导我如何操作吗?
下面是我试过的实际代码
const chopSegment = (token, frame_tag_url, tag_to_delete_id, chopped_tag_array, tags_for_index_update) => (dispatch) => {
let req = fetch(frame_tag_url + tag_to_delete_id + "/",
{
method: "DELETE",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
}
})
req.then(response => {
if (!response.ok) {
throw response;
}
else
return response.json();
}).then(response => {
return fetch(frame_tag_url,
{
method: "POST",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json",
},
body : JSON.stringify(tags_for_index_update)
}).then(response1 => {
if (!response1.ok) {
throw response1;
}
return response1.json();
}).then(response => {
for(let i = 0; i < chopped_tag_array.length; i++){
return fetch(frame_tag_url,
{
method: "POST",
body: JSON.stringify(chopped_tag_array[i]),
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
}
})
.then(response2 => {
if (!response2.ok) {
throw response2;
}
return response2.json();
}).then(response2 => {
dispatch(chopSegmentSuccess(response2))
}).catch(error => {
})
}
}).catch(error => {
})
}).catch(error => {
})
}
在上面的代码中,只有第一个 fecth ("DELETE") 被执行。随后的提取不会被执行。
您应该在前一个回调(在 "then" 内)中调用以下 "fetches",或者将它们链接起来:fetch(...).then(...).then(...)...
您可以使用 async/await 关键字改进语法。请看:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
看来您的方向是正确的。对于承诺,您通常希望使 .then
链尽可能线性。这是使用 promise 链执行操作的正确方法(我重构了一些功能以提高可读性)
const throwIfNotOk = response => {
if (!response.ok) throw response
return response
}
const deleteTag = (url, token) => fetch(url, {
method: "DELETE",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
},
})
const postTagForIndexUpdate = (url, tag) => fetch(url, {
method: "POST",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
},
body: JSON.stringify(tag),
})
const chopSegment = (
token,
frame_tag_url,
tag_to_delete_id,
chopped_tag_array,
tags_for_index_update,
) => dispatch => {
return deleteTag(frame_tag_url + tag_to_delete_id + "/")
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
.then(() => {
return postTagForIndexUpdate(frame_tag_url, tags_for_index_update)
})
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
.then(() => {
const promises = []
for (let i = 0; i < chopped_tag_array.length; i++) {
promises.push(
postTagForIndexUpdate(frame_tag_url, chopped_tag_array[i])
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
)
}
return Promise.all(promises)
})
.then(response => { dispatch(response) })
.catch(error => {
// handle error
})
}
你可以使用像 rubico
这样的承诺库来变得更干净
import { pipe, map } from 'rubico'
const chopSegment = (
token,
frame_tag_url,
tag_to_delete_id,
chopped_tag_array,
tags_for_index_update,
) => dispatch => pipe([
() => deleteTag(frame_tag_url + tag_to_delete_id + "/"),
throwIfNotOk,
response => response.json(),
() => postTagForIndexUpdate(frame_tag_url, tags_for_index_update),
throwIfNotOk,
response => response.json(),
() => chopped_tag_array,
map(pipe([
chopped_tag => postTagForIndexUpdate(frame_tag_url, chopped_tag),
throwIfNotOk,
response => response.json(),
])),
dispatch,
])
我必须一个接一个地执行三个获取请求。也就是说,假设我的三个获取请求是:
const A = (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
const B = (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
const C= (url) => (dispatch) => {
let req = fetch(url, ....)
.then(response => {
if (!response.ok) {
throw response;
}
return response.json();
}).then(response => {
}).catch(error => {
})
}
首先应该执行"A",然后在A完成时执行B,然后在B完成时执行C。一旦A,B,C完成,我想执行一个函数
doSomething = () => {
//do something after A, B, C are executed
}
我是 "promises" 的新手。有人可以指导我如何操作吗?
下面是我试过的实际代码
const chopSegment = (token, frame_tag_url, tag_to_delete_id, chopped_tag_array, tags_for_index_update) => (dispatch) => {
let req = fetch(frame_tag_url + tag_to_delete_id + "/",
{
method: "DELETE",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
}
})
req.then(response => {
if (!response.ok) {
throw response;
}
else
return response.json();
}).then(response => {
return fetch(frame_tag_url,
{
method: "POST",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json",
},
body : JSON.stringify(tags_for_index_update)
}).then(response1 => {
if (!response1.ok) {
throw response1;
}
return response1.json();
}).then(response => {
for(let i = 0; i < chopped_tag_array.length; i++){
return fetch(frame_tag_url,
{
method: "POST",
body: JSON.stringify(chopped_tag_array[i]),
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
}
})
.then(response2 => {
if (!response2.ok) {
throw response2;
}
return response2.json();
}).then(response2 => {
dispatch(chopSegmentSuccess(response2))
}).catch(error => {
})
}
}).catch(error => {
})
}).catch(error => {
})
}
在上面的代码中,只有第一个 fecth ("DELETE") 被执行。随后的提取不会被执行。
您应该在前一个回调(在 "then" 内)中调用以下 "fetches",或者将它们链接起来:fetch(...).then(...).then(...)...
您可以使用 async/await 关键字改进语法。请看:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
看来您的方向是正确的。对于承诺,您通常希望使 .then
链尽可能线性。这是使用 promise 链执行操作的正确方法(我重构了一些功能以提高可读性)
const throwIfNotOk = response => {
if (!response.ok) throw response
return response
}
const deleteTag = (url, token) => fetch(url, {
method: "DELETE",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
},
})
const postTagForIndexUpdate = (url, tag) => fetch(url, {
method: "POST",
headers: {
"Authorization": "Token " + token,
"content-type": "application/json"
},
body: JSON.stringify(tag),
})
const chopSegment = (
token,
frame_tag_url,
tag_to_delete_id,
chopped_tag_array,
tags_for_index_update,
) => dispatch => {
return deleteTag(frame_tag_url + tag_to_delete_id + "/")
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
.then(() => {
return postTagForIndexUpdate(frame_tag_url, tags_for_index_update)
})
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
.then(() => {
const promises = []
for (let i = 0; i < chopped_tag_array.length; i++) {
promises.push(
postTagForIndexUpdate(frame_tag_url, chopped_tag_array[i])
.then(response => { return throwIfNotOk(response) })
.then(response => { return response.json() })
)
}
return Promise.all(promises)
})
.then(response => { dispatch(response) })
.catch(error => {
// handle error
})
}
你可以使用像 rubico
这样的承诺库来变得更干净import { pipe, map } from 'rubico'
const chopSegment = (
token,
frame_tag_url,
tag_to_delete_id,
chopped_tag_array,
tags_for_index_update,
) => dispatch => pipe([
() => deleteTag(frame_tag_url + tag_to_delete_id + "/"),
throwIfNotOk,
response => response.json(),
() => postTagForIndexUpdate(frame_tag_url, tags_for_index_update),
throwIfNotOk,
response => response.json(),
() => chopped_tag_array,
map(pipe([
chopped_tag => postTagForIndexUpdate(frame_tag_url, chopped_tag),
throwIfNotOk,
response => response.json(),
])),
dispatch,
])