一个接一个地执行三个获取请求

问题描述 投票:-1回答:1

我必须一个接一个地执行三个fetch请求。也就是说,假设我的三个fetch请求是。

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
}

我对 "承诺 "很陌生。谁能指导我怎么做?

以下是我的实际代码,我试了一下

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")被执行。后续的fetch没有被执行。

javascript promise fetch es6-promise
1个回答
1
投票

看起来你的方向是对的。对于承诺,你通常希望让 .then 链尽可能的线性。下面是你对承诺链的正确做法(我重构了一些功能,以方便可读)。

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
  })
}

你可以通过使用一个承诺库,比如 卢比科

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,
])

-1
投票

你应该在前一个的回调中(在 "then "里面)调用下面的 "fetches",或者连锁调用。fetch(...).then(...).then(...)...

你可以通过使用asyncawait关键字来改进语法。请大家看一下。

https:/developer.mozilla.orgen-USdocsWebJavaScriptReferenceStatementsasync_function。

© www.soinside.com 2019 - 2024. All rights reserved.