내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
인스턴스화된 XMLHttpRequest 객체에는 중단 메서드도 있습니다.
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
}
전송 직후 중단된 경우 취소
// xhr的取消操作:执行过程比较模糊,不知道abort什么时机进行处理
xhr.abort()
타이머 도중(타이머 지속 시간이 인터페이스 요청 지속 시간과 유사한 경우) 요청을 취소하면 리소스를 획득한 것으로 표시되지만 콘솔에는 인쇄되지 않습니다.
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));
요청을 취소하려면 직접 중단을 사용하세요.
ac.abort()
여기에 보고된 오류의 이유는 오류가 캡처되지 않았기 때문입니다.
// 修改后的代码
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属性中
왜 이렇게 취소가 가능한가요?
fetch는 신호 객체의 상태를 모니터링하고 요청을 종료할 수 있습니다.
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");
작업이 완료되기 전에 중단될 수 있도록 수행 중인 비동기 작업과 통신할 수 있도록 하는 신호 개체를 나타내는 데 사용되는 인터페이스입니다.
중단된 AbortSignal 개체를 만드는 데 사용되는 정적 메서드입니다. 이 메서드를 호출하면 중단 상태가 true인 AbortSignal 인스턴스가 반환됩니다.
const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}
코드를 실행하기 전에 AbortSignal이 중단되었는지 확인하는 데 사용됩니다. AbortSignal이 중단된 경우 AbortError가 발생합니다. 이 방법은 개발자가 불필요한 처리를 피하기 위해 특정 작업을 수행하기 전에 중단되지 않았는지 확인하는 데 도움이 될 수 있습니다.
const signalAbout = AbortSignal.abort('abortedReason');
try {
signalAbout.throwIfAborted(); // 抛出error: abortedReason
} catch (error) {
console.log(error);
}
지정된 시간 후에 자동으로 종료되는 AbortSignal 개체를 만드는 데 사용됩니다. 이는 요청 시간 제한을 설정해야 할 때 유용합니다.
// 使用 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은 중단 이벤트를 수신하는 데 사용되며 EventTarget은 이벤트 리스너를 추가, 제거 및 트리거하는 메커니즘을 제공하므로 EventTarget에서 상속됩니다.
const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {
console.log("aborted: ", e);
})
e의 인쇄는 다음과 같습니다.
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
하나의 요소에 여러 개의 이벤트 리스너를 추가하는 경우에는 RemoveEventListener처럼 취소할 필요가 없으며, 각 이벤트는 한 번만 취소해야 하며, 매번 해당 이벤트의 이벤트 핸들을 작성해야 합니다.
신호를 사용할 때 신호를 한 번만 취소하면 모든 이벤트 모니터링이 취소됩니다.
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(); // 只需要取消一次
})
네트워크 속도가 좋지 않을 때 지속적인 네트워크 요청을 취소하는 방법은 무엇입니까?
const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {
requestData(signal); // 多个串行或者并行的接口
drawAndRender(signal); // 异步渲染
}
try{
fetchAndRenderAction({signal})
}catch{
// dosomething...
}
사용자가 적극적으로 페이지를 떠나거나 사용자의 네트워크가 매우 정체된 경우(예상 반환 순서는 인터페이스 1 => 인터페이스 2이지만 인터페이스 1의 반환이 너무 느려서 순서가 혼란스러워집니다.) 이를 위해서는 수동이 필요합니다. 요청 종료. 생성자 AbortController의 인스턴스 세마포 신호(ref로 저장 가능), 신호는 가져오기의 매개변수로 사용됩니다. 각 요청에서 중단 메소드를 수동으로 호출하여 이전 요청을 취소할 수 있습니다.
도움이 되셨다면 관심을 가져주시길 바랍니다. 기술 문서를 정기적으로 업데이트하여 모두가 함께 토론하고 배우고 발전할 수 있도록 하겠습니다.