minhas informações de contato
Correspondência[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
Há também um método abort no objeto XMLHttpRequest instanciado.
const xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(e) {
console.log(this.responseText);
});
xhr.open('GET', 'https://jsonplaceholder.typicode.com/todos/1');
xhr.send();
// 返回
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
Se abortado logo após o envio, cancele
// xhr的取消操作:执行过程比较模糊,不知道abort什么时机进行处理
xhr.abort()
Se você cancelar a solicitação durante o cronômetro (quando a duração do cronômetro for semelhante à duração da solicitação da interface), você descobrirá que o recurso foi obtido, mas não há impressão no console.
const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos/1";
fetch(url, { signal })
.then((res) => res.json())
.then((json) => console.log(json));
Use abortar diretamente para cancelar a solicitação
ac.abort()
O motivo do erro relatado aqui é que o erro não foi capturado.
// 修改后的代码
fetch(url, { signal: ac.signal })
.then((res) => res.json())
.then((json) => console.log(json))
.catch(e => console.log(e)) // DOMException: signal is aborted without reason
ac.abort() // abort接受一个入参,会被传递到signal的reason属性中
Por que pode ser cancelado assim?
fetch monitora o status do objeto de sinal e pode encerrar a solicitação
const ac = new AbortController();
const { signal } = ac;
const url = "https://jsonplaceholder.typicode.com/todos";
const todoRequest = (id, { signal }) => {
fetch(`${url}/${id}`, { signal })
.then((res) => res.json())
.then((json) => console.log(json))
.catch((e) => console.log(e)); // DOMException: signal is aborted without reason
};
todoRequest(1, { signal });
todoRequest(2, { signal });
todoRequest(3, { signal });
ac.abort("cancled");
é uma interface usada para representar um objeto de sinal que permite a comunicação com uma operação assíncrona que está sendo executada para que a operação possa ser abortada antes de ser concluída.
Método estático usado para criar um objeto AbortSignal abortado. Quando você chama esse método, ele retorna uma instância AbortSignal com status abortado verdadeiro.
const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}
Usado para verificar se o AbortSignal foi abortado antes de executar o código. Se AbortSignal foi abortado, lançará um AbortError. Este método pode ajudar os desenvolvedores a garantir que não sejam abortados antes de executar uma operação específica para evitar processamento desnecessário.
const signalAbout = AbortSignal.abort('abortedReason');
try {
signalAbout.throwIfAborted(); // 抛出error: abortedReason
} catch (error) {
console.log(error);
}
Usado para criar um objeto AbortSignal que termina automaticamente após um tempo especificado. Isto é útil quando você precisa definir um tempo limite de solicitação.
// 使用 AbortSignal.timeout 设置 10ms超时
const signalAbout = AbortSignal.timeout(10);
const todoRequest = (id, { signal }) => {
fetch(`${url}/${id}`, { signal })
.then((res) => res.json())
.then((json) => console.log("json: ", json))
.catch((e) => console.log("err: ", e)); //DOMException: signal timed out
};
todoRequest(1, { signal: signalAbout });
AbortSignal herda de EventTarget, porque AbortSignal é usado para escutar eventos de anulação e EventTarget fornece um mecanismo para adicionar, remover e acionar ouvintes de eventos.
const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {
console.log("aborted: ", e);
})
A impressão de e é a seguinte:
const ac = new AbortController();
const { signal } = ac;
const cancelablePromise = ({signal}) =>
new Promise((resolve, reject) => {
// 情况1:直接主动取消
signal?.throwIfAborted(); // 也可以用reject
// 情况2:正常处理业务逻辑
setTimeout(() => {
Math.random() > 0.5 ? resolve('data') : reject('fetch error');
}, 1000);
// 情况3:超时 todo?
// 监听取消
signal.addEventListener("abort", () => {
reject(signal?.reason);
});
})
// 发起网络请求
cancelablePromise({signal})
.then(res => console.log('res: ', res))
.catch(err => console.log('err: ', err))
// 情况1
// ac.abort('用户离开页面了') // err: 用户离开页面了
// 情况2 正常请求 err: fetch error || res: data
Quando vários ouvintes de eventos são adicionados a um elemento, ele não precisa ser cancelado como removeEventListener. Cada evento precisa ser cancelado uma vez e o identificador do evento correspondente deve ser gravado a cada vez.
Ao usar o sinal, você só precisa cancelar o sinal uma vez e todo o monitoramento de eventos será cancelado.
const ac = new AbortController();
const { signal } = ac;
const eleA = document.querySelector('#a');
const eleB = document.querySelector('#b');
function aEleHandler () {}; // 事件
eleA.addEventListener('click', aEleHandler, {signal}); // 无论绑定多少个事件,都只需要一个signal
eleB.addEventListener('click', () => {
ac.abort(); // 只需要取消一次
})
Como cancelar esta solicitação contínua de rede quando a velocidade da rede não é boa?
const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {
requestData(signal); // 多个串行或者并行的接口
drawAndRender(signal); // 异步渲染
}
try{
fetchAndRenderAction({signal})
}catch{
// dosomething...
}
Quando o usuário sai ativamente da página ou a rede do usuário está muito travada (a ordem de retorno esperada é: interface 1 => interface 2; mas o retorno da interface 1 é muito lento, fazendo com que o pedido fique confuso). encerramento do pedido. O sinal do semáforo de instância do construtor AbortController (pode ser armazenado como ref), o sinal é usado como parâmetro de busca. A cada solicitação, o método abort pode ser chamado manualmente para cancelar a solicitação anterior.
Se for útil para você, fique atento. Atualizarei a documentação técnica regularmente para que todos possam discutir, aprender e progredir juntos.