-
-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add rejectLate option #12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I should also update the README, which I'll do if I get the indication this is gonna land. |
This seems surprising. If you have const promiseCallLimit = require('./')
const pass = async () => new Promise(r => setTimeout(() => {
console.log('pass')
r()
}))
const fail = async () => new Promise((_, r) => setTimeout(() => {
console.log('fail')
r('nope')
}))
promiseCallLimit([
pass,
fail,
pass,
pass,
pass,
pass,
pass,
], 2, true).then(console.log, console.error)
// Expect 6 passes logged, 1 fail
// Actual:
// pass
// fail
// pass
// nope |
Or is |
2572937
to
105f4a7
Compare
Yes, the idea is that if any in-flight promise rejects, no new ones are started, but all in-flight promises finish before that first rejection bubbles up. Any extra rejections are disregarded. |
Consider: diff --git a/index.js b/index.js
index afba90d..e6a8a63 100644
--- a/index.js
+++ b/index.js
@@ -36,20 +36,20 @@ const callLimit = (queue, limit = defLimit, rejectLate) => new Promise((res, rej
const run = () => {
const c = current++
if (c >= queue.length) {
- return resolve()
+ return rejected ? reject() : resolve()
}
active ++
results[c] = queue[c]().then(result => {
active --
results[c] = result
- if (!rejected)
+ if (!rejected || rejectLate)
run()
return result
}, (er) => {
active --
reject(er)
- }).finally(result => {
+ }).then(result => {
if (rejectLate && rejected && active === 0)
return rej(rejection)
return result
|
I see. That seems fine, and is what this does, but should definitely be documented, because it's easy to assume that rejectLate will behave like promise-all-reject-late, where all promises are guaranteed to resolve before returning. |
Maybe instead of a |
This makes the The existing tests also never catch the entirety of ETA: Oh does this run all promises? That'd be a good implementation of "reject last" as I'm calling it. |
I'd love to switch to an options object. I opted for a non-breaking change for the initial PR. |
As far as the "reject late" vs "reject last" distinction, that isn't something npm itself needs but I can see folks eventually wanting it. |
Since we're in net new territory if folks want ALL the promises to run they really want a |
Took a stab at an opts object and updating the readme. |
1d133f1
to
e39e8c4
Compare
Yeah, that's when I thought the intent was for |
It's entirely possible my initial assumption about how I also assumed this was the behavior we'd want in npm, but it's very likely I was wrong. Ignoring my assumption so that we can try to get rid of the scope creep here, what do you think the minimum implementation of this should be here? |
BREAKING CHANGE: the function now expects an opts parameter
e39e8c4
to
7b9a105
Compare
Rewrote the PR to discard the idea of stopping at the first rejection. |
|
||
const callLimit = (queue, limit = defLimit) => new Promise((res, rej) => { | ||
const callLimit = (queue, { limit = defLimit, rejectLate } = {}) => new Promise((res, rej) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking change
Closes: #1