依次执行三个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,
])