Κοινή χρήση τεχνολογίας

Πώς να ακυρώσετε την κλήση διεπαφής στο μπροστινό μέρος

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

🧑‍💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣

1. Πώς το xmlHttpRequest ακυρώνει το αίτημα;

Υπάρχει επίσης μια μέθοδος ματαίωσης στο αρχικό αντικείμενο 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();

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
// 返回
{
  "userId": 1,
  "id": 1,
  "title": "delectus aut autem",
  "completed": false
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Εάν ματαιωθεί αμέσως μετά την αποστολή, ακυρώστε

// xhr的取消操作:执行过程比较模糊,不知道abort什么时机进行处理
xhr.abort()

  • 1
  • 2
  • 3

Εάν ακυρώσετε το αίτημα κατά τη διάρκεια του χρονοδιακόπτη (όταν η διάρκεια του χρονοδιακόπτη είναι παρόμοια με τη διάρκεια του αιτήματος διεπαφής), θα διαπιστώσετε ότι ο πόρος έχει ληφθεί, αλλά δεν υπάρχει εκτύπωση στην κονσόλα.
Εισαγάγετε την περιγραφή της εικόνας εδώ

2. AbortController

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));

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Χρησιμοποιήστε το abort απευθείας για να ακυρώσετε το αίτημα

ac.abort()

  • 1
  • 2

Εισαγάγετε την περιγραφή της εικόνας εδώ
Ο λόγος για το σφάλμα που αναφέρεται εδώ είναι ότι το σφάλμα δεν καταγράφηκε.

// 修改后的代码
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属性中

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Γιατί μπορεί να ακυρωθεί έτσι;

Το fetch παρακολουθεί την κατάσταση του αντικειμένου σήματος και μπορεί να τερματίσει το αίτημα

2.1 Πώς να ακυρώσετε πολλά αιτήματα ταυτόχρονα;

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");

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Εισαγάγετε την περιγραφή της εικόνας εδώ

2.2 AbortSignal

είναι μια διεπαφή που χρησιμοποιείται για την αναπαράσταση ενός αντικειμένου σήματος που σας επιτρέπει να επικοινωνείτε με μια ασύγχρονη λειτουργία που εκτελείται έτσι ώστε η λειτουργία να μπορεί να ματαιωθεί πριν ολοκληρωθεί.

2.3 Μέθοδος AbortSignal

2.3.1 ματαίωση

Στατική μέθοδος που χρησιμοποιείται για τη δημιουργία ενός ματαιωμένου αντικειμένου AbortSignal. Όταν καλείτε αυτήν τη μέθοδο, επιστρέφει ένα στιγμιότυπο AbortSignal με την κατάσταση ματαίωσης true.

const signalAbout = AbortSignal.abort(); // AbortSignal {aborted: true, reason: DOMException: signal is aborted without reason...}

  • 1
  • 2

2.3.2 μέθοδος throwIfAborted

Χρησιμοποιείται για να ελέγξει εάν το AbortSignal έχει ματαιωθεί πριν από την εκτέλεση του κώδικα. Εάν το AbortSignal έχει ματαιωθεί, θα εμφανίσει ένα AborError. Αυτή η μέθοδος μπορεί να βοηθήσει τους προγραμματιστές να διασφαλίσουν ότι δεν θα ματαιωθούν πριν από την εκτέλεση μιας συγκεκριμένης λειτουργίας για να αποφευχθεί η περιττή επεξεργασία.

const signalAbout = AbortSignal.abort('abortedReason');
try {
    signalAbout.throwIfAborted(); // 抛出error: abortedReason
} catch (error) {
    console.log(error);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.3.3 τάιμ άουτ

Χρησιμοποιείται για τη δημιουργία ενός αντικειμένου 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 });

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Εισαγάγετε την περιγραφή της εικόνας εδώ

2.3.3.1 Προσθήκη προγράμματος ακρόασης συμβάντων => από μη τερματισμένο σε τερματισμένο

Το AbortSignal κληρονομεί από το EventTarget, επειδή το AbortSignal χρησιμοποιείται για την ακρόαση συμβάντων ματαίωσης και το EventTarget παρέχει έναν μηχανισμό για την προσθήκη, αφαίρεση και ενεργοποίηση ακρόασης συμβάντων.

const signalAbout = AbortSignal.timeout(10);
signalAbout.addEventListener("abort", (e) => {
    console.log("aborted: ", e);
})
​

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Η εκτύπωση του e έχει ως εξής:
Εισαγάγετε την περιγραφή της εικόνας εδώ

3. Εφαρμόστε μια προληπτικά ακυρωμένη υπόσχεση

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

4. Πώς να χρησιμοποιήσετε το σήμα για να ακυρώσετε την ακρόαση συμβάντων;

Όταν προστίθενται πολλαπλοί ακροατές συμβάντων σε ένα στοιχείο, δεν χρειάζεται να ακυρωθεί όπως το 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(); // 只需要取消一次
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

5. Σενάρια όπου ζητούνται πολλαπλές διεπαφές για τη συναρμολόγηση δεδομένων

Πώς να ακυρώσετε αυτό το συνεχές αίτημα δικτύου όταν η ταχύτητα του δικτύου δεν είναι καλή;

const ac = new AbortController();
const { signal } = ac;
const fetchAndRenderAction = (signal) => {
    requestData(signal); // 多个串行或者并行的接口
    drawAndRender(signal); // 异步渲染
}
​
try{
    fetchAndRenderAction({signal})
}catch{
    // dosomething...
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

6. Περίληψη

Όταν ο χρήστης εγκαταλείπει ενεργά τη σελίδα ή το δίκτυο του χρήστη είναι πολύ κολλημένο (η αναμενόμενη σειρά επιστροφής είναι: διεπαφή 1 => διεπαφή 2, αλλά η επιστροφή της διεπαφής 1 είναι πολύ αργή, προκαλώντας σύγχυση στην παραγγελία.) Αυτό απαιτεί μη αυτόματο καταγγελία του αιτήματος. Το σήμα σηματοφόρου του κατασκευαστή AbortController (μπορεί να αποθηκευτεί ως ref), το σήμα χρησιμοποιείται ως παράμετρος ανάκτησης Σε κάθε αίτημα, η μέθοδος ματαίωσης μπορεί να καλείται χειροκίνητα για να ακυρώσει το προηγούμενο αίτημα.

Εάν είναι χρήσιμο για εσάς, μπορείτε να δώσετε προσοχή, θα ενημερώνω τακτικά την τεχνική τεκμηρίωση, ώστε όλοι να μπορούν να συζητούν, να μαθαίνουν και να σημειώνουν πρόοδο.
Εισαγάγετε την περιγραφή της εικόνας εδώ