Comments (25)
I'm assuming you want to execute a promise-returning function unless it is already running.
Since I can't add a module, here's how it would work:
const pStateThrottle = async function_ => {
let isRunning = false
return (...arguments_) => {
if (!isRunning) {
try {
isRunning = true
return await function_(…arguments_)
} finally {
isRunning = false
}
}
}
}
const action = pStateThrottle(async () => {
await delay(3000)
alert("Waited 3 seconds")
})
button.onclick = action
from promise-fun.
Looks good. I'd use try/finally to return the value and ensure that the state is always updated
try {
isRunning = true
return await function_(…arguments_)
} finally {
isRunning = false
}
from promise-fun.
@Richienb You don't need the boolean then.
from promise-fun.
@fregante Or a separate method? debounce.single
/debounce.wait
/debounce.one
.
Also, related issue: sindresorhus/p-debounce#3
from promise-fun.
I wonder if this could be an option or separate method to https://github.com/sindresorhus/p-debounce
from promise-fun.
Alternative names:
p-dedupe
p-deduplicate
p-ensure-one
from promise-fun.
Just nitpick, I would make it return early:
const pStateThrottle = async function_ => {
let isRunning = false
return (...arguments_) => {
if (isRunning) {
return
}
try {
isRunning = true
return await function_(…arguments_)
} finally {
isRunning = false
}
}
}
const action = pStateThrottle(async () => {
await delay(3000)
alert("Waited 3 seconds")
})
button.onclick = action
from promise-fun.
Currently, when called a second time, it will just resolve the promise right away. That's fine for this specific use-case, but I think it might be better to store the promise and return that instead. That way the second call would wait for the original delay to finish too.
from promise-fun.
I think it might be better to store the promise and return that instead.
const pStateThrottle = function_ => {
let currentPromise
return async (...arguments_) => {
if (currentPromise) {
return currentPromise
}
try {
currentPromise = function_(...arguments_)
return await currentPromise
} finally {
currentPromise = undefined
}
}
}
const action = pStateThrottle(async () => {
await delay(3000)
alert("Waited 3 seconds")
})
button.onclick = action
from promise-fun.
I wonder if this could be an option or separate method to sindresorhus/p-debounce
Only if it's an alternative to the timer rather than an addition (i.e. just "wait for the promise", never "wait for the promise and the timer")
Given that none of the options apply to this behavior, the signature can become:
function debounce(fn, [wait, [options]])
No wait
means it just waits for the Promise.
Alternatively it could be p-one-pending
because deduplication makes me think of memoization
from promise-fun.
debounce.promise
would make the most sense to me, or debounce.whilePending
?
from promise-fun.
Debouncing queues extra calls to be run after a delay whereas throttling dumps extra calls without ever executing them. We are actually throttling function calls so we should add it to https://github.com/sindresorhus/p-throttle.
from promise-fun.
Debouncing queues extra calls to be run after a delay
No, debouncing does not queue calls. Only p-debounce
returns the same promise for all the calls, but usually debouncers drop calls and return undefined
. In fact they're often used in event listeners like window.onresize = debounce(callback, 300)
so that they're only called once the resize events stop.
Throttling calls the function "no more often than every X milliseconds", so I don't think it applies here.
from promise-fun.
Therefore, this should result in one alert
:
const action = debounce.promise(async () => {
delay(3000);
alert('Done')!
})
action();
action();
from promise-fun.
I've begun implementing this in p-debounce
and I've come to this realisation: What is this supposed to do?
const action = debounce.promise(async value => {
delay(3000);
return value
})
action("a");
action("b");
Right now, it throws away "b"
which leads to unpredictable results as the second call will resolve with a
.
Do we want to queue up calls instead of discarding them in a separate implementation in p-throttle
?
from promise-fun.
Right now, it throws away
"b"
which leads to unpredictable results as the second call will resolve witha
.
That's what debounce
does, it discards calls:
Do we want to queue up calls instead of discarding them in a separate implementation in
p-throttle
?
Throttle discards calls too. You're thinking of queues, which neither debounce
nor throttle
are.
from promise-fun.
Throttle discards calls too. You're thinking of queues, which neither
debounce
northrottle
are.
p-throttle
defines queue
:
from promise-fun.
Indeed.
How's p-throttle
different from p-limit? It appears the same down to the concurrency option.
p-throttle
is the only "throttle" module that behaves this way. See this example, none of them execute the calls 2, and 3 except p-throttle.
https://runkit.com/bfred-it/5ffe7a7977172c001b32528f
from promise-fun.
p-throttle is the only "throttle" module that behaves this way. See this example, none of them execute the calls 2, and 3 except p-throttle.
Yeah, I don't remember why I made it like that. Seems you're not the only confused one: sindresorhus/p-throttle#15 Maybe we should add a discard
option and make it default to true
? That way the default behavior is the expected one and users can set it to false
to get the old behavior.
from promise-fun.
Since this new function also discards calls, does it still make sense for it to be added to p-debounce
?
from promise-fun.
Yeah, I don't remember why I made it like that
If I think about it it does make sense as it does throttle calls; the only issue is that it doesn't match the meaning throttle
has in the JS community.
How's
p-throttle
different from p-limit?
Answering myself: p-limit
doesn't have an interval
parameter
from promise-fun.
I think this should/could be part of p-memoize
:
- it supports multiple calls at once, as long as the parameters are different
- can support "one call at once regardless of parameters" by just passing
cacheKey: () => {}
probably
In practice this is identical but opposite to cachePromiseRejection
. I'll open an issue there.
from promise-fun.
Alternative names:
p-dedupe
p-deduplicate
p-ensure-one
I suggest the name p-collapse
, as the behavior is similar to request collapsing on CDNs.
Request collapsing is the practice of combining multiple requests for the same object into a single request to origin, and then using the resulting response to satisfy all pending requests.
from promise-fun.
Closing in favor of sindresorhus/p-memoize#20
from promise-fun.
@fregante you may be interested in https://github.com/TehShrike/gate-keeper
from promise-fun.
Related Issues (9)
- p-map + p-queue HOT 1
- How to access the state of a promise synchronously?
- Add caolan/async HOT 2
- p-map for a function or p-whilst with concurrency HOT 2
- Run async function return values HOT 6
- Move .then/.catch-based modules to their own section HOT 1
- p-prefetch or p-iterable? HOT 13
- p-* version for promise-queue(max-concurrent=1, max-lenght=1) HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from promise-fun.