Sự khác biệt giữa điều chỉnh và gỡ lỗi một chức năng


250

Bất cứ ai cũng có thể cho tôi một lời giải thích bằng những từ đơn giản về sự khác biệt giữa điều tiết và gỡ lỗi một chức năng cho các mục đích giới hạn tỷ lệ.

Đối với tôi cả hai dường như làm điều tương tự. Tôi đã kiểm tra hai blog này để tìm hiểu:

http://remysharp.com/2010/07/21/throttling-feft-calls

http://benalman.com/projects/jquery-thrption-debounce-plugin/


102
demo.nimius.net/debounce_thrption là một hình ảnh trực quan tốt
thriqon

4
@thriqon rằng trực quan tốt hơn mô tả của tôi.
Donal

Vâng, điều đó cũng giúp tôi hiểu khái niệm này ... +1 cho tác giả gốc ;-)
thriqon

Ví dụ rất đơn giản đã giúp tôi hiểu. jsfiddle.net/Voronar/sxjy25ew/1
Kirill A. Khalitov

1
Có thể xem trực quan ở đây cũng như codepen.io/chriscoyier/pen/vOZNQV
trungk18

Câu trả lời:


345

Nói một cách đơn giản:

  • Throttling sẽ trì hoãn thực hiện một chức năng. Nó sẽ làm giảm các thông báo của một sự kiện phát sinh nhiều lần.
  • Việc thảo luận sẽ tập hợp một loạt các lệnh gọi tuần tự đến một hàm thành một lệnh gọi đến hàm đó. Nó đảm bảo rằng một thông báo được thực hiện cho một sự kiện phát sinh nhiều lần.

Bạn có thể thấy sự khác biệt ở đây

Nếu bạn có một chức năng được gọi rất nhiều - ví dụ: khi sự kiện thay đổi kích thước hoặc di chuyển chuột xảy ra, nó có thể được gọi rất nhiều lần. Nếu bạn không muốn hành vi này, bạn có thể tiết lưu nó để hàm được gọi đều đặn. Tranh luận sẽ có nghĩa là nó được gọi ở cuối (hoặc bắt đầu) của một loạt các sự kiện.


9
Tôi nghĩ rằng liên kết trực quan của thriqon cho thấy cách nó hoạt động rất tốt. Nếu bạn có một chức năng được gọi rất nhiều - ví dụ: khi sự kiện thay đổi kích thước hoặc di chuyển chuột xảy ra, nó có thể được gọi rất nhiều lần. Nếu bạn không muốn điều này, bạn có thể điều chỉnh nó để chức năng được gọi đều đặn. Nợ sẽ có nghĩa là nó được gọi ở cuối (hoặc bắt đầu) của một loạt các cuộc gọi.
Donal

10
@AdamM. Có một cái nhìn trực quan ở đây: demo.nimius.net/debounce_thrption
Donal

2
@AdamM. Không. Bạn có thể hình dung điều này bằng cách di chuyển chuột trong bản demo và dừng di chuyển chuột mỗi lần một lần. Thanh gỡ lỗi sẽ "đánh dấu" sau khi bạn dừng tất cả chuyển động của chuột, trong khi thanh tiết lưu sẽ tiếp tục "đánh dấu" trong khi chuột di chuyển, nhưng với tốc độ giảm (tiết lưu).
John Weisz

26
Tôi hoàn toàn loooove hình dung. Cảm ơn!
Sammi

4
Liên kết có giá trị hơn hàng ngàn từ
Finesse

148

Cá nhân tôi thấy debounce khó hiểu hơn ga .

Vì cả hai chức năng đều giúp bạn trì hoãn và giảm tỷ lệ thực hiện. Giả sử bạn đang gọi các chức năng được trang trí được trả về bằng cách điều chỉnh / gỡ lỗi liên tục ...

  • Van tiết lưu : chức năng ban đầu được gọi nhiều nhất một lần trong một khoảng thời gian xác định.
  • Gỡ lỗi : chức năng ban đầu được gọi sau khi người gọi dừng gọi chức năng trang trí sau một khoảng thời gian xác định .

Tôi tìm thấy phần cuối cùng của việc ra mắt rất quan trọng để hiểu mục tiêu mà nó đang cố gắng đạt được. Tôi cũng tìm thấy một phiên bản cũ của việc triển khai _.debounce giúp hiểu biết (lịch sự của https://davidwalsh.name/feft-debounce ).

// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
_.debounce = function(func, wait, immediate) {
  var timeout;
  return function() {
    var context = this, args = arguments;
    var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
    };
    var callNow = immediate && !timeout;
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    if (callNow) func.apply(context, args);
  };
};

Một phép ẩn dụ xa vời, nhưng có lẽ cũng có thể giúp đỡ.

Bạn có một người bạn tên Chatty, người thích nói chuyện với bạn qua IM. Giả sử khi cô ấy nói chuyện, cô ấy sẽ gửi một tin nhắn mới cứ sau 5 giây, trong khi biểu tượng ứng dụng IM của bạn đang nảy lên và xuống, bạn có thể lấy ...

  • Cách tiếp cận ngây thơ : kiểm tra mọi tin nhắn miễn là nó đến. Khi biểu tượng ứng dụng của bạn bị trả lại, hãy kiểm tra. Đó không phải là cách hiệu quả nhất, nhưng bạn luôn cập nhật.
  • Cách tiếp cận bướm ga : cứ sau 5 phút bạn lại kiểm tra một lần (khi có cái mới). Khi có tin nhắn mới, nếu bạn đã kiểm tra bất cứ lúc nào trong 5 phút cuối, hãy bỏ qua nó. Bạn tiết kiệm thời gian của bạn với phương pháp này, trong khi vẫn còn trong vòng lặp.
  • Cách tiếp cận gỡ lỗi : bạn biết Chatty, cô ấy chia toàn bộ câu chuyện thành từng mảnh, gửi chúng trong một tin nhắn khác. Bạn đợi cho đến khi Chatty kết thúc toàn bộ câu chuyện: nếu cô ấy dừng gửi tin nhắn trong 5 phút, bạn sẽ cho rằng cô ấy đã kết thúc, bây giờ bạn kiểm tra tất cả.

17
Không hiểu sự khác biệt giữa 2 chức năng này cho đến khi tôi đọc nó. Cảm ơn
Seamus Barrett

7
Phép ẩn dụ là một trong những ví dụ tuyệt vời nhất mà tôi từng đọc về điều tiết và gỡ lỗi. Cảm ơn.
Vignesh

96

Sự khác biệt

+--------------+-------------------+-------------------+
|              |  Throttle 1 sec   |  Debounce 1 sec   |
+--------------+-------------------+-------------------+
| Delay        | no delay          | 1 sec delay       |
|              |                   |                   |
| Emits new if | last was emitted  | there is no input |
|              | before 1 sec      |  in last 1 sec    |
+--------------+-------------------+-------------------+

Giải thích theo trường hợp sử dụng :

  • Thanh tìm kiếm- Không muốn tìm kiếm mỗi khi người dùng nhấn phím? Muốn tìm kiếm khi người dùng dừng gõ trong 1 giây. Sử dụng debounce1 giây khi bấm phím.

  • Trò chơi bắn súng - Súng lục mất 1 giây thời gian giữa mỗi lần bắn nhưng người dùng nhấp chuột nhiều lần. Sử dụng throttlekhi nhấp chuột.

Đảo ngược vai trò của họ :

  • Điều chỉnh 1 giây trên thanh tìm kiếm - Nếu người dùng nhập abcdefghijvới mỗi ký tự 0.6 sec. Sau đó ga sẽ kích hoạt ở lần anhấn đầu tiên . Nó sẽ bỏ qua mọi lần nhấn trong 1 giây tiếp theo, tức là b.6 giây sẽ bị bỏ qua. Sau đó cở 1,2 giây sẽ kích hoạt lại, thiết lập lại thời gian một lần nữa. Vì vậy, dsẽ được bỏ qua và esẽ được kích hoạt.

  • Súng ngắn xuất hiện trong 1 giây- Khi người dùng nhìn thấy kẻ thù, anh ta nhấp chuột, nhưng nó sẽ không bắn. Anh ta sẽ bấm lại vài lần trong giây đó nhưng nó sẽ không bắn. Anh ta sẽ xem nếu nó vẫn còn đạn, tại thời điểm đó (1 giây sau lần nhấp cuối cùng) súng sẽ tự động bắn.


37

Điều chỉnh thực thi một số lần tối đa một chức năng có thể được gọi theo thời gian. Như trong "thực hiện chức năng này nhiều nhất cứ sau 100 mili giây."

Tranh luận thực thi rằng một chức năng không được gọi lại cho đến khi một khoảng thời gian nhất định trôi qua mà không được gọi. Như trong "chỉ thực hiện chức năng này nếu 100 mili giây đã trôi qua mà không được gọi."

tham chiếu


20

Van tiết lưu (1 giây): Xin chào, tôi là robot. Miễn là bạn tiếp tục làm phiền tôi, tôi sẽ tiếp tục nói chuyện với bạn, nhưng sau mỗi giây chính xác. Nếu bạn ping tôi để trả lời trước khi một giây trôi qua, tôi vẫn sẽ trả lời bạn trong khoảng thời gian chính xác là 1 giây. Nói cách khác, tôi chỉ thích trả lời theo những khoảng thời gian chính xác.

Ra mắt (1 giây): Xin chào, tôi là ^^ anh em họ của robot. Miễn là bạn tiếp tục làm phiền tôi, tôi sẽ giữ im lặng vì tôi chỉ muốn trả lời sau khi 1 giây trôi qua kể từ lần cuối bạn ping tôi . Tôi không biết, nếu đó là vì tôi có vấn đề về thái độ hoặc vì tôi không muốn làm phiền mọi người. Nói cách khác, nếu bạn tiếp tục yêu cầu tôi trả lời trước 1 giây kể từ lần gọi cuối cùng của bạn, bạn sẽ không bao giờ nhận được trả lời. Vâng vâng ... hãy tiếp tục! gọi tôi là thô lỗ.


Van tiết lưu (10 phút): Tôi là một máy khai thác gỗ. Tôi gửi nhật ký hệ thống đến máy chủ phụ trợ của chúng tôi, sau khoảng thời gian thông thường là 10 phút.

Ra mắt (10 giây): Xin chào, tôi không phải là anh em họ của máy khai thác gỗ đó. (Không phải mọi debouncer có liên quan đến một throttler trong thế giới tưởng tượng này). Tôi làm bồi bàn ở một nhà hàng gần đó. Tôi nên cho bạn biết rằng miễn là bạn tiếp tục thêm đồ vào đơn đặt hàng, tôi sẽ không vào bếp để thực hiện đơn hàng của bạn. Chỉ khi hết 10 giây sau khi bạn sửa đổi đơn đặt hàng lần cuối, tôi sẽ cho rằng bạn đã hoàn tất đơn đặt hàng. Chỉ sau đó tôi sẽ thực hiện đơn đặt hàng của bạn trong nhà bếp.


Bản giới thiệu thú vị: https://css-tricks.com/debouncing-throttling-explained-examples/

Tín dụng cho sự tương tự người phục vụ: https://codeburst.io/throttling-and-debouncing-in-javascript-b01cad5c8edf


1
giải thích tốt nhất.
Karan Sharma

17

Ghi nợ cho phép bạn quản lý tần suất của các cuộc gọi mà một chức năng có thể nhận được. Nó kết hợp nhiều cuộc gọi xảy ra trên một chức năng nhất định để các cuộc gọi lặp lại xảy ra trước khi hết thời gian cụ thể bị bỏ qua. Về cơ bản việc thảo luận đảm bảo rằng chính xác một tín hiệu được gửi cho một sự kiện có thể xảy ra nhiều lần.

Điều chỉnh giới hạn tần suất của các cuộc gọi mà một chức năng nhận được trong một khoảng thời gian cố định. Nó được sử dụng để đảm bảo rằng hàm mục tiêu không được gọi thường xuyên hơn độ trễ được chỉ định. Điều chỉnh là giảm tỷ lệ của một sự kiện lặp lại.


17

Thật đơn giản.

Họ thực hiện chính xác điều tương tự (giới hạn tốc độ) ngoại trừ khi van tiết lưu được gọi là nó sẽ kích hoạt chức năng được bọc của bạn theo định kỳ và sẽ không được gỡ lỗi. Gỡ lỗi chỉ (cố gắng) gọi chức năng của bạn một lần vào cuối.

Ví dụ : Nếu bạn đang cuộn, bướm ga sẽ từ từ gọi chức năng của bạn trong khi bạn cuộn (cứ sau X mili giây). Gỡ lỗi sẽ đợi cho đến khi bạn cuộn xong để gọi chức năng của mình.


Điều đáng chú ý là trong các bản demo này, chúng có thể trông không giống "vì bản phát hành sẽ luôn kích hoạt X mili giây sau sự kiện cuối cùng, trong khi cuộc gọi cuối cùng của bướm ga có thể xảy ra sớm hơn (và nó không cần phải gọi lại khi thông báo sẽ phát ra ). nó khá là không quan trọng, nhưng đáng nói nếu bạn nhìn vào các bản demo.
Ryan Taylor

16

Trong điều khoản của Giáo dân:

Việc gỡ lỗi sẽ ngăn một chức năng chạy trong khi nó vẫn được gọi thường xuyên. Một hàm được gỡ lỗi sẽ chỉ chạy sau khi nó được xác định rằng nó không còn được gọi nữa, tại thời điểm đó nó sẽ chạy chính xác một lần. Ví dụ thực tế về tranh luận:

  • Tự động lưu hoặc xác thực nội dung của trường văn bản nếu người dùng "dừng gõ": thao tác sẽ chỉ được thực hiện một lần, SAU KHI đã xác định rằng người dùng không còn gõ (không còn nhấn phím).

  • Ghi nhật ký nơi người dùng nghỉ chuột: người dùng không còn di chuyển chuột, vì vậy vị trí (cuối cùng) có thể được ghi lại.

Điều chỉnh đơn giản sẽ ngăn một chức năng chạy nếu nó chạy gần đây, bất kể tần số cuộc gọi. Ví dụ thực tế của điều tiết:

  • Việc triển khai v-sync dựa trên điều chỉnh: màn hình sẽ chỉ được vẽ nếu 16ms trôi qua kể từ lần rút màn hình cuối cùng. Cho dù chức năng làm mới màn hình được gọi bao nhiêu lần, nó sẽ chỉ chạy tối đa một lần trong mỗi 16ms.

7

Một sự tương tự trong cuộc sống thực mà cá nhân giúp tôi nhớ:

  • ra mắt = một cuộc trò chuyện . bạn đợi người khác nói xong trước khi trả lời.
  • ga = một bit trống . bạn chỉ chơi ghi chú trên một bit trống 4/4 đơn giản.

Các trường hợp sử dụng để gỡ lỗi :

  • Đánh máy. Bạn muốn làm một cái gì đó sau khi người dùng ngừng gõ. Vì vậy, chờ đợi 1 giây sau lần nhấn phím cuối cùng có ý nghĩa. Mỗi tổ hợp phím khởi động lại chờ đợi.
  • Hoạt hình. Bạn muốn thu nhỏ lại một phần tử sau khi người dùng ngừng di chuột qua nó. Không sử dụng gỡ lỗi có thể gây ra một hình ảnh động thất thường do con trỏ vô tình di chuyển giữa các vùng "nóng" và "lạnh".

Các trường hợp sử dụng cho ga :

  • Cuộn. Bạn muốn phản ứng với việc cuộn nhưng giới hạn số lượng tính toán được thực hiện, do đó, làm gì đó cứ sau 100ms là đủ để ngăn ngừa độ trễ tiềm năng.
  • Chuột di chuyển. Tương tự như cuộn nhưng để di chuyển chuột.
  • API gọi Bạn muốn bắn một cuộc gọi API trên sự kiện UI nhất định nhưng muốn giới hạn số lượng cuộc gọi API bạn thực hiện không quá tải máy chủ của bạn.

4

throtle chỉ là một wrapper quanh debounce mà làm trễ để gọi thông qua functiontrong một khoảng thời gian, nếu debounce trì hoãn một cuộc gọi chức năng trên khoảng thời gian đó là lớn hơn sau đó theo quy định tại throtle .



2

Điều tiết

Điều chỉnh thực thi một số lần tối đa một chức năng có thể được gọi là làm thêm giờ. Như trong "thực hiện chức năng này nhiều nhất cứ sau 100 mili giây." Nói trong trường hợp bình thường, bạn sẽ gọi chức năng này 1.000 lần trong 10 giây. Nếu bạn điều tiết nó chỉ một lần trong 100 mili giây, nó sẽ chỉ thực hiện chức năng đó tối đa 100 lần

(10s * 1,000) = 10,000ms
10,000ms / 100ms throttling = 100 maximum calls

Tranh luận

Tranh luận thực thi rằng một chức năng không được gọi lại cho đến khi một khoảng thời gian nhất định trôi qua mà không được gọi. Như trong "chỉ thực hiện chức năng này nếu 100 mili giây đã trôi qua mà không được gọi."

Có lẽ một chức năng được gọi là 1.000 lần trong một vụ nổ nhanh, phân tán trong 3 giây, sau đó dừng được gọi. Nếu bạn đã phát hành nó ở tốc độ 100 mili giây, chức năng sẽ chỉ kích hoạt một lần, ở mức 3,1 giây, khi vụ nổ kết thúc. Mỗi lần hàm được gọi trong khi nổ, nó sẽ đặt lại bộ đếm thời gian gỡ lỗi

nguồn: - ga và thảo luận


2

Giả sử chúng ta có một hàm gọi lại "cb" để được gọi trong sự kiện "E". Để "E" được kích hoạt 1000 lần trong 1 giây, do đó sẽ có 1000 cuộc gọi đến "cb". Đó là 1 cuộc gọi / ms. Để tối ưu hóa chúng ta có thể sử dụng:

  • Điều tiết : Với điều chỉnh (100ms), "cb" sẽ được gọi vào [100 giây, 200 giây, 300 giây, ... 1000 giây]. Đó là 1 cuộc gọi / 100 ms. Tại đây 1000 cuộc gọi đến "cb" được tối ưu hóa thành 10 cuộc gọi.
  • Tranh chấp : Với việc phát hành (100ms), "cb" sẽ chỉ được gọi một lần vào [1100 giây]. Đó là 100ms sau lần kích hoạt cuối cùng của "E" xảy ra vào [1000 giây ms]. Tại đây 1000 cuộc gọi đến "cb" được tối ưu hóa thành 1 cuộc gọi.

1

Theo như tôi hiểu, theo cách hiểu đơn giản, Throttling - tương tự như gọi setInterval (gọi lại) trong một số lần nhất định tức là gọi cùng một hàm cho số lần nhất định theo thời gian xảy ra sự kiện và .. Gỡ lỗi - tương tự như gọi setTImeout (callbackForApi) hoặc gọi một chức năng sau một thời gian nhất định đã qua khi xảy ra sự kiện. Liên kết này có thể hữu ích- https://css-tricks.com/the-difference-b between-throttling-and-debouncing /

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.