τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
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));
Χρησιμοποιήστε το abort απευθείας για να ακυρώσετε το αίτημα
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. Όταν καλείτε αυτήν τη μέθοδο, επιστρέφει ένα στιγμιότυπο AbortSignal με την κατάσταση ματαίωσης true.
const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}
Χρησιμοποιείται για να ελέγξει εάν το AbortSignal έχει ματαιωθεί πριν από την εκτέλεση του κώδικα. Εάν το AbortSignal έχει ματαιωθεί, θα εμφανίσει ένα AborError. Αυτή η μέθοδος μπορεί να βοηθήσει τους προγραμματιστές να διασφαλίσουν ότι δεν θα ματαιωθούν πριν από την εκτέλεση μιας συγκεκριμένης λειτουργίας για να αποφευχθεί η περιττή επεξεργασία.
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, επειδή το AbortSignal χρησιμοποιείται για την ακρόαση συμβάντων ματαίωσης και το 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), το σήμα χρησιμοποιείται ως παράμετρος ανάκτησης Σε κάθε αίτημα, η μέθοδος ματαίωσης μπορεί να καλείται χειροκίνητα για να ακυρώσει το προηγούμενο αίτημα.
Εάν είναι χρήσιμο για εσάς, μπορείτε να δώσετε προσοχή, θα ενημερώνω τακτικά την τεχνική τεκμηρίωση, ώστε όλοι να μπορούν να συζητούν, να μαθαίνουν και να σημειώνουν πρόοδο.