如何在 componentWillUnmount 中中止 运行 async/await xmlHttpRequest?

How to abort running async/await xmlHttpRequest within componentWillUnmount?

这是代码...您将如何中止这样的 ajax 调用?

或者,如何防止反应给我一个错误"setState called on unmounted component"?

(httpGet 只是 XMLHttpRequest 的包装器和一个 promise)

async componentDidMount() {
    const response = await httpGet("/ajaxRequest");
    if(response) {
        //the component has already been unmounted
        this.setState(() => ({success: true}));
    }
}

componentWillUnmount() {
    //should abort possible running ajax
}

编辑: 这是包装纸:

const httpGet = function (url) {


    const request = new XMLHttpRequest;
    request.open("GET", url, true);

    return new Promise((resolve, reject) =>  {
        request.onload(response => {
            resolve(response);
        });

        request.onerror(() => {
            reject("Network error");
        });

        request.send();
    });
};

为了能够随时中止它,XMLHttpRequest 包装器应该:

  • 要么 return 带有承诺的请求对象本身。

  • 或在包装器外部创建请求。

  • 或使用 sub/pub 库(如 mufa 或 redux)。

我会选择第二个选项

const httpGet = function (url, request = new XMLHttpRequest()) { // 2 arguments 

    request.open("GET", url, true);

    return new Promise((resolve, reject) =>  {
        request.onload(response => {
            resolve(response);
        });

        request.onerror(() => {
            reject("Network error");
        });

        request.send();
    });
};

现在 componentDidMount :

async componentDidMount() {
    this.request = new XMLHttpRequest();
    const response = await httpGet("/ajaxRequest", this.request);
    if(response) {
        //the component has already been unmounted
        this.setState(() => ({success: true}));
    }
}

现在 componentWillUnmount:

componentWillUnmount() {
  if (this.request && this.request.abort) {
    this.request.abort();
  }
}

就这么简单。 如果你不想中止,那么你的第一个包装器(httpGet)仍然有效,因为第二个参数(请求)是可选的。