-
Notifications
You must be signed in to change notification settings - Fork 29.6k
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
doc: more use-cases for promise events #3438
Conversation
Please consider the discussion in #979 before merging.
and #979 (comment) |
Basically, summing up the pending issues I have with it:
When these gets addressed I'm all for merging. |
|
||
function SomeResource() { | ||
// Initially set the loaded status to a rejected promise | ||
this.loaded = Promise.reject(new Error('Resource not yet loaded!')); |
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.
This patten is confusing to me. How does data actually get there once loaded?
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.
I have not shown a complete implementation of SomeResource. I could do so if it would help. Essentially there's a SomeResource.prototype.load() method that will replace the promise with a successful one.
The idea is that anyone doing .loaded.then(...)
before anything is loaded goes down the error path. Whereas, after something is loaded, they go down the success path.
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.
I fleshed this out in full painful detail https://gist.github.com/domenic/854f0dc0f698a63b0e8a. I think including all that would be way too much for the docs, but if there's a way to make it clearer, I'm happy to do so.
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.
That makes sense.
I'm fine with merging this, if it better highlights the potentially leaky aspect of the unhandledRejections set and the fact that, at any given time, not all items in unhandledRejections are necessarily in a state that they would never be handled. As for my comment on making it a topic doc, I don't think that should be a blocker, but should be something we think about in the future. As yet, the non-reference docs situation is not yet entirely nailed down. |
}); | ||
|
||
You could then record this list in some error log, either periodically or upon | ||
process exit. This would avoid the false positive seen in the above resource |
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.
Maybe better: "This would then only expose the developer errors as shown above in'unhandledRejection'
example."
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.
Sure, since some people are allergic to the term false positive that seems like a good way to defuse the situation.
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.
You could then record this list in some error log, either periodically or upon process exit. This would avoid the false positive
This doesn't avoid the false positive. It makes a false positive significantly less likely. I don't think those are the same thing, but if there is otherwise consensus then I won't object it.
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.
Used @Fishrock123's phrasing
Can you suggest some phrasing? All I can think of is "since the unhandledRejection set lives for the lifetime of your program, it will consume memory for the lifetime of your program, the same as every other object that lives for the lifetime of your program." |
I tried to cover this in the existing text with "unlike in synchronous code where there is |
d39c1cf
to
07d7a2b
Compare
I don't think it's very good to make an example that is essentially a memory leak and then basically say "btw this obviously leaks memory, figure out some way to avoid that". There is just no way to phrase that well. The example should be fixed so that there is no inherent memory leak to begin with e.g. some interval that periodically clears the list or such. |
}); | ||
|
||
You could then record this list in some error log, either periodically or upon | ||
process exit. This would then only expose the developer errors as shown above | ||
in the `'unhandledRejection'` example. |
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.
Perhaps it is better to reword and put this into the 'unhandledRejection'
part, it's missing context here.
"below is an example ..."
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.
I rephrased it, hopefully in a way that addresses @petkaantonov's concerns as well.
07d7a2b
to
6489d4a
Compare
I'm not 100% sure about the entire pre-populate error-promise as a notification thing, but the wording of the rest of the docs now appears sound. I'll let others chime in. |
// no .catch or .then on resource.loaded for at least a turn | ||
|
||
To deal with cases like this, which you may not want to track as developer | ||
error in the same way as other `'unhandledRejection'` events, you can either |
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.
"which you may not want to track as developer error in the same way as other 'unhandledRejection'
events"
Sentence structure is a little weird here, also "errors".
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.
Split into two sentences and rephrased a bit.
6489d4a
to
fd50bcd
Compare
@domenic I think the wording needs to make more reference to the content of the set, not the existence of the set. It will continue to be a single set through the life of the program, but the content could grow over time. In an app that is not sufficiently handling promises, it could grow to the point of consuming all memory and terminating the app. I'm not sure I agree exactly with @petkaantonov on the need for code to clear the list, just due to the verbosity of that, but at least explaining that real code would need to do that is important, I think. |
fd50bcd
to
9e98329
Compare
@Qard at the cost of some extra verbosity, expanded the last paragraph along those lines. |
LGTM |
lgtm |
This is much better - what about the constructor example? I'd be happy if we changed that a bit. |
9e98329
to
6047052
Compare
This adds an example of a semi-common promise pattern that could result in false-positive 'unhandledRejection' events, to help motivate why there is a dual 'rejectionHandled' event. I anticipate it being helpful to users who encounter 'unhandledRejection' events that do not stem from obvious typos such as the JSON.pasre example. Also cleans up the promise rejection tracking sample. By using a Map instead of array we can get O(1) deletion and actually record the errors. And, fixed indentation and backtick usage there to align with the rest of the document.
I saw an interesting use case today, what about something like the following? var promises = [];
myEventEmitter.on("data", url => {
promises.push(makeRequest(url));
}).on("done", () => Promise.all(promises).then(results => {
// do work
}); Without suppressing the error Again, other than that LGTM. |
To clarify - as I said in my last two comments - it looks good to me, further improvements can go to a new PRs. The tone I do not appreciate so much but I can live with it :) |
LGTM. Will land. |
This adds an example of a semi-common promise pattern that could result in false-positive 'unhandledRejection' events, to help motivate why there is a dual 'rejectionHandled' event. I anticipate it being helpful to users who encounter 'unhandledRejection' events that do not stem from obvious typos such as the JSON.pasre example. Also cleans up the promise rejection tracking sample. By using a Map instead of array we can get O(1) deletion and actually record the errors. And, fixed indentation and backtick usage there to align with the rest of the document. Reviewed-By: Stephan Belanger <admin@stephenbelanger.com> Reviewed-By: Petka Antonov <petka.antonov@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> PR-URL: #3438
Landed in d381290 |
This adds an example of a semi-common promise pattern that could result in false-positive 'unhandledRejection' events, to help motivate why there is a dual 'rejectionHandled' event. I anticipate it being helpful to users who encounter 'unhandledRejection' events that do not stem from obvious typos such as the JSON.pasre example. Also cleans up the promise rejection tracking sample. By using a Map instead of array we can get O(1) deletion and actually record the errors. And, fixed indentation and backtick usage there to align with the rest of the document. Reviewed-By: Stephan Belanger <admin@stephenbelanger.com> Reviewed-By: Petka Antonov <petka.antonov@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> PR-URL: #3438
should this be in lts? |
Could be but not a pressing need.
|
This adds an example of a semi-common promise pattern that could result in false-positive 'unhandledRejection' events, to help motivate why there is a dual 'rejectionHandled' event. I anticipate it being helpful to users who encounter 'unhandledRejection' events that do not stem from obvious typos such as the JSON.pasre example. Also cleans up the promise rejection tracking sample. By using a Map instead of array we can get O(1) deletion and actually record the errors. And, fixed indentation and backtick usage there to align with the rest of the document. Reviewed-By: Stephan Belanger <admin@stephenbelanger.com> Reviewed-By: Petka Antonov <petka.antonov@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> PR-URL: #3438
Landed in v4.x-staging in bb73029 |
This adds an example of a semi-common promise pattern that could result in false-positive 'unhandledRejection' events, to help motivate why there is a dual 'rejectionHandled' event. I anticipate it being helpful to users who encounter 'unhandledRejection' events that do not stem from obvious typos such as the JSON.pasre example. Also cleans up the promise rejection tracking sample. By using a Map instead of array we can get O(1) deletion and actually record the errors. And, fixed indentation and backtick usage there to align with the rest of the document. Reviewed-By: Stephan Belanger <admin@stephenbelanger.com> Reviewed-By: Petka Antonov <petka.antonov@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> PR-URL: #3438
This adds an example of a semi-common promise pattern that could
result in false-positive 'unhandledRejection' events, to help motivate
why there is a dual 'rejectionHandled' event. I anticipate it being
helpful to users who encounter 'unhandledRejection' events that do not
stem from obvious typos such as the JSON.pasre example.
Also cleans up the promise rejection tracking sample. By using a Set
instead of array we can get O(1) deletion. And, fixed indentation and
backtick usage there to align with the rest of the document.
Supercedes #979. Hopefully things can be more civil this time.