Skip to content

Comments

feat(async/unstable): allow setting dynamic timeframe for throttle#7002

Open
lionel-rowe wants to merge 6 commits intodenoland:mainfrom
lionel-rowe:throttle-dynamic
Open

feat(async/unstable): allow setting dynamic timeframe for throttle#7002
lionel-rowe wants to merge 6 commits intodenoland:mainfrom
lionel-rowe:throttle-dynamic

Conversation

@lionel-rowe
Copy link
Contributor

@lionel-rowe lionel-rowe commented Feb 13, 2026

Closes #6796.

If fn returns a promise, lastExecution is now based on the asynchronous end time of the previous completed call. For example with this function:

async function fn() {
    const start = performance.now()
    while (performance.now() - start < 50) { /* idle  loop */ }
    await new Promise((res) => setTimeout(res, 100))
}

If the throttled function is called once at time 0 and we observe lastExecution:

Observation time Current implementation New implementation
0 -Infinity -Infinity
100 ~50 -Infinity
200 ~50 ~150

This will also affect how throttling works with asynchronous functions — the current implementation basically doesn't throttle at all for typical async functions, whereas the new one does.

@lionel-rowe lionel-rowe requested a review from kt3k as a code owner February 13, 2026 01:05
@github-actions github-actions bot added the async label Feb 13, 2026
@lionel-rowe lionel-rowe changed the title feat(async/unstable): allow setting dynamic timeframe for throttle feat(async/unstable): allow setting dynamic timeframe for throttle Feb 13, 2026
@lionel-rowe lionel-rowe marked this pull request as draft February 13, 2026 01:22
@codecov
Copy link

codecov bot commented Feb 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.22%. Comparing base (823ee48) to head (f36b9ea).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7002      +/-   ##
==========================================
+ Coverage   94.21%   94.22%   +0.01%     
==========================================
  Files         615      617       +2     
  Lines       47840    48591     +751     
  Branches     8320     8539     +219     
==========================================
+ Hits        45074    45787     +713     
- Misses       2699     2736      +37     
- Partials       67       68       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lionel-rowe lionel-rowe marked this pull request as ready for review February 13, 2026 17:09
*/
// deno-lint-ignore no-explicit-any
export function throttle<T extends Array<any>>(
fn: (this: ThrottledFunction<T>, ...args: T) => void,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return type of the function should be updated to match the new async handling, something like void | PromiseLike<void>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about that but actually returning a promise doesn't really make sense, as the wrapped function doesn't always run and so the return value should be treated as meaningless and discarded, i.e. should be void/undefined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, the return value is discarded. So I guess the benefit of adding PromiseLike is to signal/document fn?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, the return value is discarded. So I guess the benefit of adding PromiseLike is to signal/document fn?

Sorry, I don't follow. PromiseLike is not part of the signature, but promise-likes do now have special handling to enable lastExecution to track their time-to-resolve rather than time-to-sync-return.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't follow. PromiseLike is not part of the signature, but promise-likes do now have special handling to enable lastExecution to track their time-to-resolve rather than time-to-sync-return.

It was more of a cosmetic thing. Totally fine to keep it like this ☺️

@kt3k
Copy link
Member

kt3k commented Feb 16, 2026

@lionel-rowe Can you also add an example with comment about when to use the new option?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@std/async throttle dynamically adjusted timeframe

3 participants