informasi kontak saya
Surat[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
Ada juga metode pembatalan pada objek XMLHttpRequest yang dipakai.
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
}
Jika dibatalkan langsung setelah dikirim, batalkan
// xhr的取消操作:执行过程比较模糊,不知道abort什么时机进行处理
xhr.abort()
Jika Anda membatalkan permintaan selama penghitung waktu (ketika durasi penghitung waktu mirip dengan durasi permintaan antarmuka), Anda akan menemukan bahwa sumber daya telah diperoleh, tetapi tidak ada cetakan di konsol.
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));
Gunakan batalkan secara langsung untuk membatalkan permintaan
ac.abort()
Alasan kesalahan yang dilaporkan di sini adalah karena kesalahan tersebut tidak terekam.
// 修改后的代码
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属性中
Kenapa bisa dibatalkan seperti ini?
ambil memonitor status objek sinyal dan dapat menghentikan permintaan
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");
adalah antarmuka yang digunakan untuk mewakili objek sinyal yang memungkinkan Anda berkomunikasi dengan operasi asinkron yang sedang dilakukan sehingga operasi dapat dibatalkan sebelum selesai.
Metode statis yang digunakan untuk membuat objek AbortSignal yang dibatalkan. Saat Anda memanggil metode ini, metode ini mengembalikan instance AbortSignal dengan status true yang dibatalkan.
const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}
Digunakan untuk memeriksa apakah AbortSignal telah dibatalkan sebelum mengeksekusi kode. Jika AbortSignal telah dibatalkan, AbortError akan muncul. Metode ini dapat membantu pengembang memastikan bahwa mereka tidak dibatalkan sebelum melakukan operasi tertentu untuk menghindari pemrosesan yang tidak perlu.
const signalAbout = AbortSignal.abort('abortedReason');
try {
signalAbout.throwIfAborted(); // 抛出error: abortedReason
} catch (error) {
console.log(error);
}
Digunakan untuk membuat objek AbortSignal yang otomatis berakhir setelah waktu tertentu. Ini berguna ketika Anda perlu menetapkan batas waktu permintaan.
// 使用 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 mewarisi dari EventTarget, karena AbortSignal digunakan untuk mendengarkan peristiwa yang dibatalkan, dan EventTarget menyediakan mekanisme untuk menambah, menghapus, dan memicu pendengar peristiwa.
const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {
console.log("aborted: ", e);
})
Pencetakan e adalah sebagai berikut:
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
Ketika beberapa event listening ditambahkan ke sebuah elemen, elemen tersebut tidak perlu dibatalkan seperti deleteEventListener. Setiap event perlu dibatalkan satu kali, dan event handle dari event terkait harus ditulis setiap saat.
Saat menggunakan sinyal, Anda hanya perlu membatalkan sinyal satu kali, dan semua pemantauan peristiwa akan dibatalkan.
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(); // 只需要取消一次
})
Bagaimana cara membatalkan permintaan jaringan berkelanjutan ini ketika kecepatan jaringan tidak bagus?
const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {
requestData(signal); // 多个串行或者并行的接口
drawAndRender(signal); // 异步渲染
}
try{
fetchAndRenderAction({signal})
}catch{
// dosomething...
}
Ketika pengguna aktif meninggalkan halaman, atau jaringan pengguna sangat macet (urutan pengembalian yang diharapkan adalah: antarmuka 1 => antarmuka 2; tetapi pengembalian antarmuka 1 terlalu lambat, menyebabkan urutannya menjadi bingung.) Ini memerlukan manual penghentian permintaan. Contoh sinyal semaphore dari konstruktor AbortController (dapat disimpan sebagai ref), sinyal digunakan sebagai parameter pengambilan. Pada setiap permintaan, metode pembatalan dapat dipanggil secara manual untuk membatalkan permintaan sebelumnya.
Jika bermanfaat bagi Anda, silakan memperhatikan. Saya akan memperbarui dokumentasi teknis secara berkala sehingga semua orang dapat berdiskusi, belajar, dan membuat kemajuan bersama.