React-Redux 丢弃 HTTP 请求

React-Redux Drop HTTP Request

我正在构建一个 React-Redux 应用程序,当某个 HTTP 请求正在进行时,我有一个显示取消按钮的应用程序。如果请求成功执行,UI 会显示结果,如果用户按下取消按钮,UI 会显示不同的内容。

现在我正在使用以下函数来启动我的请求并在请求完成后更新我的 Redux 存储。

export function doFetch(url) {
    return dispatch => {
        fetch(url)
            .then((json) => dispatch({type: types.MY_SUCCESS_ACTION}, json))
            .catch((error) => dispatch({type: types.MY_FAILURE_ACTION, error}));
    }
}

现在上面的代码不处理用户点击取消按钮的情况。现在 ES7 正在使用 cancelable promises 做一些工作,这可能适合我的用例,因为那时我会参考我的请求承诺,如果用户点击取消按钮,我可以取消它。

在此期间我该怎么做。我需要一些方法,以便在用户点击取消按钮时,我可以发送一个操作来丢弃当前的 HTTP 请求。

解决方案

import Bluebird from 'bluebird';
Bluebird.config({
    cancellation: true
});
fetch.promise = Bluebird;
let curReqPromises = [];    

function doFetch(url) {
        return dispatch => {
            curReqPromises.push(bluebirdRequest(url)
                .then((json) => dispatch({type: types.MY_SUCCESS_ACTION}, json))
                .catch((error) => dispatch({type: types.MY_FAILURE_ACTION, error}));
        }
    }

    function bluebirdRequest(url) {
        return new Bluebird((resolve, reject, onCancel) => {
            makeFetch(url)
                .then((json) => resolve(json))
                .catch((error) => reject(json));

            onCancel(() => {
                console.log('I was cancelled');
            });
        });
    }

有几种方法可以取消承诺。

  1. 使用rxjs
  2. 使用bluebird

如果您对执行其中任何一个都不感兴趣,那么您可以通过创建取消操作来手动取消,然后在状态为 cancelled 时忽略该提取的结果。一旦 promise 解决,您可以将状态重置为 notCancelled 但避免从获取中更改状态。它很乱,这是 rxjs 或 bluebird 的卖点之一,它们都内置了取消功能。