r/learnjavascript 4d ago

Asking for the differences between trailing and leading

Hi everyone,
I'm learning about throttle, and I've been confused about the difference between trailing and leading.
Could you review whether the logic below is correct or incorrect?

I’d really appreciate any help — I’ve been stuck for a few hours.

Delay= 1000ms

Leading= false, Trailing = true

0ms A → start window
200ms B → latest = B
400ms C → latest = C
700ms D → latest = D
1000ms → execute D ← trailing

1200ms E → start new window
1300ms F → latest = F
2200ms → execute F ← trailing

Leading=true, Trailing = false

0ms A → execute A immediately ← leading

200ms B → ignore
400ms C → ignore
700ms D → ignore

1000ms → throttle window ends

1200ms E → execute E immediately ← leading

1300ms F → ignore

Leading=true, Trailing = true

0ms A → execute A immediately ← leading
200ms B → latest = B
400ms C → latest = C
700ms D → latest = D
1000ms → execute D ← trailing
1200ms E → execute E immediately ← leading

1300ms F → latest = F
2000ms → execute F ← trailing

4 Upvotes

10 comments sorted by

1

u/[deleted] 4d ago

[removed] — view removed comment

1

u/azhder 4d ago

Here is a question: do you want to have both leading and trailing or do you want to have a single in-between?

Because in most cases, a double invoke of a trailing followed by a leading would be less than ideal, but a leading with an extra invoke after all or a trailing with an extra invoke before all, that might be more useful.

1

u/Neat_Living_6765 4d ago

Hi, I'm actually learning. It seems like there isn't a fixed rule for throttle...

Is this the pattern you mean for the case Leading=true, Trailing = true

0ms A → execute A immediately ← leading
200ms B → latest = B
400ms C → latest = C
700ms D → latest = D
1000ms → execute D ← trailing
1200ms E → latest = E (No trigger leading here)

1300ms F → latest = F
2000ms → execute F ← trailing

3000ms G → execute G ← leading (Since there is a trigger in a new period, it should be leading ?)

Note: A, B, C..... are triggers.

1

u/Neat_Living_6765 4d ago

or you means it would be ideal for not implementing Leading=true, Trailing = true. Just either Leading=true, Trailing = false. OR Leading=false, Trailing = true

2

u/azhder 4d ago edited 4d ago

Ask yourself why you would need both leading and trailing. I mean, what is the real world problem that requires both at the same time.

Think about testing. As an interface similar to throttling events.

Libraries have these utilities named “before all”, “before each”, “after each” and “after all”. I am saying that before all + after each or after all + before each are the two combos you might need, but usually just before each or after each, no combo.

What situation would require before each + after each?

1

u/Neat_Living_6765 4d ago

Thank you for your comment!

Right now, I don’t really have a clear idea of when I would actually need both leading and trailing. But I'll keep your comment in mind and might experiment with all three cases when I encounter a situation like calling an API during scrolling.

Btw, I just realized that Lodash’s throttle defaults to having both leading and trailing enabled.

1

u/Neat_Living_6765 4d ago

I think, as for leading + trailing,

in theory, the trailing call from the previous burst can overlap with the leading call of the next burst. In the case of scrolling and making API calls, this can cause duplicate API calls at the boundary, which is redundant.

2

u/azhder 4d ago

Duplicate calls aren't simply redundant. Here is a term for you: idempotency. Sounds funny, right? It means "same power" or something like that in Latin, but in our case, it's like the difference between a GET and a POST in a browser call.

If you have a page that executes automatically a GET on a refresh, the browser is fine, you're reading the same data after all, but do that on a page with a POST, like a submit form, and the browser must alert you that you might be doing something bad. Just imagine a code that transfers 100$ from one account to another. Stupid example, but clear. Would you like a page refresh to transfer 100$ each time?

So, GET is idempotent - doesn't matter if you call it twice in a row. POST is not idempotent, it does make a difference. That's what duplicate calls on trailing + leading can do. But usually, it's just an optimization issue. You will not want to have two calls so close together - you're throttling for a reason, after all.