Các hàm gỡ lỗi trong JavaScript là các hàm bậc cao giới hạn tốc độ mà một hàm khác được gọi.
Hàm bậc cao hơn là một hàm lấy một hàm làm đối số hoặc trả về một hàm như một phần của câu lệnh trả về của nó. Chức năng gỡ lỗi của chúng tôi thực hiện cả hai.
Trường hợp sử dụng phổ biến nhất để gỡ lỗi là chuyển nó dưới dạng đối số cho trình xử lý sự kiện được đính kèm với phần tử HTML. Để hiểu rõ hơn về điều này trông như thế nào và tại sao nó lại hữu ích, hãy xem một ví dụ.
Nói rằng bạn có một chức năng có tên myFunc
được gọi mỗi khi bạn nhập nội dung nào đó vào trường nhập liệu. Sau khi xem qua các yêu cầu cho dự án của bạn, bạn quyết định rằng bạn muốn thay đổi trải nghiệm.
Thay vào đó, bạn muốn myFunc
để thực thi khi ít nhất 2 giây đã trôi qua kể từ lần cuối cùng bạn nhập nội dung nào đó.
Đây là nơi một cuộc gỡ lỗi có thể phát huy tác dụng. thay vì vượt qua myFunc
đến trình lắng nghe sự kiện, bạn sẽ chuyển vào phần gỡ lỗi. Việc gỡ lỗi sau đó sẽ mất myFunc
làm đối số, cùng với số 2000.
Bây giờ, bất cứ khi nào bạn nhấp vào nút, myFunc
sẽ chỉ thực hiện nếu ít nhất 2 giây đã trôi qua trước lần cuối cùng myFunc
được gọi là.
Cách triển khai chức năng gỡ lỗi
Từ đầu đến cuối, chỉ mất 7 dòng mã để triển khai chức năng gỡ lỗi. Phần còn lại của phần này tập trung vào 7 dòng mã đó để chúng ta có thể thấy chức năng gỡ lỗi hoạt động bên trong như thế nào.
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
timeout = setTimeout( callback, delay );
}
}
Bắt đầu từ dòng 1, chúng ta đã khai báo một hàm mới có tên debounce
. Chức năng mới này có hai tham số, callback
và delay
.
function debounce( callback, delay ) {
}
callback
là bất kỳ chức năng nào cần giới hạn số lần nó thực thi.
delay
là thời gian (tính bằng mili giây) cần trôi qua trước khi callback
có thể thực hiện lại.
function debounce( callback, delay ) {
let timeout;
}
Ở dòng 2, chúng ta đang khai báo một biến chưa khởi tạo có tên timeout
.
Biến mới này giữ timeoutID
trở lại khi chúng tôi gọi setTimeout
sau này trong chúng tôi debounce
chức năng.
function debounce( callback, delay ) {
let timeout;
return function() {
}
}
Ở dòng 3, chúng tôi đang trả về một chức năng ẩn danh. Chức năng ẩn danh này sẽ đóng trong vòng timeout
biến để chúng tôi có thể giữ quyền truy cập vào nó ngay cả sau lệnh gọi ban đầu tới debounce
đã thực hiện xong.
Một bao đóng trong JavaScript xảy ra bất cứ khi nào một chức năng bên trong vẫn giữ quyền truy cập vào phạm vi từ vựng của chức năng bên ngoài của nó, ngay cả khi chức năng bên ngoài đã thực thi xong. Nếu bạn muốn tìm hiểu thêm về bao đóng, bạn có thể đọc Chương 7 của “Bạn không biết JS” của Kyle Simpson
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
}
}
Trên dòng 4, chúng tôi đang gọi clearTimeout
phương pháp của WindowOrWorkerGlobalScope
mixin. Điều này sẽ đảm bảo rằng mỗi lần chúng tôi gọi debounce
chức năng, timeout
được đặt lại và bộ đếm có thể bắt đầu lại.
Các WindowOrWorkerGlobalScope
mixin của JavaScript cung cấp cho chúng tôi quyền truy cập vào một số phương thức nổi tiếng, như setTimeout
, clearTimeout
, setInterval
, clearInterval
và fetch
.
Bạn có thể tìm hiểu thêm về nó bằng cách đọc bài viết này.
function debounce( callback, delay ) {
let timeout;
return function() {
clearTimeout( timeout );
timeout = setTimeout( callback, delay );
}
}
Trên dòng 5, chúng tôi đã đi đến cuối debounce
thực hiện chức năng.
Dòng mã đó thực hiện một vài điều. Hành động đầu tiên là gán một giá trị cho timeout
biến mà chúng ta đã khai báo ở dòng 2. Giá trị là một timeoutID
được trả lại khi chúng tôi gọi setTimeout
. Điều này sẽ cho phép chúng tôi tham chiếu thời gian chờ được tạo bằng cách gọi setTimeout
để chúng tôi có thể thiết lập lại nó mỗi khi chúng tôi debounce
chức năng được sử dụng.
Hành động thứ hai được thực hiện là gọi setTimeout
. Điều này sẽ tạo ra một thời gian chờ sẽ thực thi callback
(đối số chức năng được chuyển đến của chúng tôi debounce
chức năng) một lần delay
(đối số số được truyền cho debounce
chức năng) đã trôi qua.
Vì chúng tôi đang sử dụng thời gian chờ, callback
sẽ chỉ thực thi nếu chúng tôi cho phép thời gian chờ đạt 0. Đây là nơi trung tâm của chúng tôi debounce
chức năng hoạt động vì chúng tôi đang đặt lại thời gian chờ mỗi lần debounce
được gọi là. Đây là những gì cho phép chúng tôi giới hạn tốc độ thực hiện của myFunc
.
Dòng 5 và 6 chỉ chứa dấu ngoặc nên chúng ta sẽ không lướt qua chúng.
Đó là nó. Đó là cách của chúng tôi debounce
chức năng hoạt động nội bộ. Bây giờ hãy thêm vào ví dụ trước của chúng ta ngay từ đầu. Chúng tôi sẽ tạo một trường nhập liệu và đính kèm một trình lắng nghe sự kiện với debounce
hoạt động như một trong các đối số của nó.
Ví dụ thế giới thực
Đầu tiên, chúng ta cần tạo một trường nhập liệu.
<label for="myInput">Type something in!</label>
<input id="myInput" type="text">
Tiếp theo, chúng ta cần tạo một hàm mà chúng ta muốn thực thi bất cứ khi nào chúng ta nhập nội dung nào đó vào trường nhập liệu của mình.
function helloWorld() {
console.log("Hello World!")
}
Cuối cùng, chúng ta cần chọn trường nhập liệu mà chúng ta đã tạo ở trên và đính kèm một keyup
người nghe sự kiện cho nó.
const myInput = document.getElementById("myInput");
myInput.addEventListener(
"keyup",
debounce( helloWorld, 2000 )
);
Điều đó kết thúc ví dụ thế giới thực của chúng tôi! Mỗi khi chúng tôi nhập nội dung nào đó vào trường nhập liệu của mình, helloWorld
sẽ thực thi nếu ít nhất 2 giây đã trôi qua kể từ lần cuối cùng chúng tôi nhập nội dung nào đó.
Đặc biệt cảm ơn người dùng Reddit máy đo địa tầng để giúp sửa một số mã ban đầu trong bài viết này. Đây là một bản demo hoạt động mà anh ấy đã tạo ra
debounce
chức năng trên Repl.it.
Ghi chú kết thúc
Các hàm gỡ lỗi là các hàm đơn giản nhưng mạnh mẽ có thể có tác động rõ rệt đối với hầu hết các ứng dụng JavaScript.
Mặc dù ví dụ của chúng tôi thú vị và đơn giản nhưng nhiều tổ chức lớn sử dụng chức năng gỡ lỗi để tăng hiệu suất cho ứng dụng của họ.
Nếu bạn muốn tìm hiểu thêm về JavaScript, hãy xem trang web của tôi! Tôi đang làm một số thứ hay ho tại https://juanmvega.com.