繁体   English   中英

AbortController 提前中止

[英]AbortController aborting ahead of time

我想要实现的是在用户更改过滤器后中止先前的请求。
我试过这个:

const API_URL = "https://www.example.com"

const controller = new AbortController();
const signal = controller.signal;

export const fetchData = async (filters) => {
    // this console.log is fired only once
    console.log("Below I thought it would abort a request if ongoing, and ignore otherwise");
    controller.abort();
    const response = await fetch(`${API_URL}/products?${filters}`, { method: "GET", signal });
    return await response.json();
}

但是发生的情况是,即使在第一次调用时,我的请求也会提前中止。
我尝试的另一件事是像这样管理AbortController

let controller;
let signal;

export const fetchData = async (filters) => {
    if (controller) {
        console.log("aborting")
        controller.abort();
        controller = null;
        fetchData(filters); // won't work until I invoke this function here recursively
        // and I expected something like 
        // controller = new AbortController();
        // signal = controller.signal;
        // ... then the rest of the function would work
    } else {
        controller = new AbortController();
        signal = controller.signal;
    }
    const response = await fetch(`${API_URL}/products?${filters}`, { method: "GET", signal });
    console.log("fetch fulfilled")
    return await response.json();
}

但是如果我不包含fetchData的递归调用,上述方法将不起作用,因为调用controller.abort()导致整个 function 在if块之后抛出错误并且直到最后才执行。
如果它有效,这会让我很高兴,但是"fetch fulfilled"被注销了两次。 为什么?

当已经有 controller 时,您将同时调用fetchData (在if分支中)稍后进行 fetch; 该分支不会终止 function。 所以你最终得到了两个提取和两个“已完成”的消息。

简化代码应该把它整理出来(见***注释):

let controller; // Starts out with `undefined`

export const fetchData = async (filters) => {
    // Abort any previous request
    controller?.abort(); // *** Note the optional chaining
    controller = new AbortController(); // *** Controller for this request
    const response = await fetch(`${API_URL}/products?${filters}`, {
        method: "GET",
        signal: controller.signal, // *** Using this controller's signal
    });
    console.log("fetch fulfilled");
    // *** Note: You need a check `response.ok` here
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    return await response.json();
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM