-
Notifications
You must be signed in to change notification settings - Fork 24
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
Are unresolved promises rejected prior to a window.unload event? #44
Comments
Interesting question! As the spec is structured right now, unloading does not run any code except the I suspect that this design is somewhat intentional; unloading is a complicated process, and we want to run as little script as possible during it. But I do not know the full history. In theory we could restructure the spec to make rejection work. E.g., we could add "perform a microtask checkpoint" after step 11. (Or, I guess you could even have your spec's document cleanup steps perform a microtask checkpoint.) But, re-entering the event loop during the very last phases of unloading seems bad... @bzbarsky may have more insights on this. |
I'm generally opposed to pages running any script in unload; it's rarely used for anything good. I'd remove the unload event if I could. Does that help? ;) |
Yeah, I think that settles it. So @mrj, just leave the promises pending; no need to add cleanup steps, since script wouldn't be able to react to them anyway. Unsure how or whether to incorporate this into the promises guide... it's kind of a niche thing. Maybe it'd be worthwhile noting in some way that promise callbacks cannot run during unload. |
On the off chance there's a general design question here, we had a similar (but not the same) question in WebRTC where promise-returning methods on the RTCPeerConnection object are even allowed to queue up in certain circumstances. After |
Thanks for your thoughts. I'm just thinking of practical uses for explicit rejection: making it easy to process the fact and the reason (fired unload flag of document is set or window.closed property set?) that NFC data hasn't been sent or received -- to warn the user (possibly so the unload can be stopped), to save unsent data, to substitute unreceived data, or just for analytic purposes. Without rejection, one would have to do this in an unload handler via variables that enumerate the active promises. This is what has currently been chosen as the unload behaviour of the Web NFC API. |
That behavior seems quite bad. It is a may, so it varies across browsers. It cancels things even though an unload might not happen, so if there's a beforeunload handler that prevents unloading, you still shut down all your NFC stuff. And it uses the undefined terminology "when an object receives the You should instead use the unloading document cleanup steps to run that, and probably a note saying "since no microtasks run during document unload, the promise rejections that happen are not observable." |
Although no user interaction is possible in a I agree that it's wrong to specify that the NFC shutdown (including promise rejection) MAY happen during And, as you mention, you can't really attach this NFC shutdown algorithm to a particular event. It has to be attached to a browser micro-task sequence. So either NFC has to go it alone in specifying a rejection step, or a standard way needs to be specified. |
Because no microtasks run after step 11. The event loop has already shut down, so any handlers queued with
Please don't do this. You've heard explicitly from an implementer that authors should not run code while the browsing context is being unloaded. You should not be adding patterns to encourage that kind of problematic author code. Especially not if you are explicitly doing it to encourage synchronous Ajax calls. |
If it's widely believed that synchronous Ajax calls during unload are intrinsically bad (because they cause a delay or lock-up at an unexpected time?), then there's no good reason to reject promises. Determined developers will still hack around this by attaching to the |
Why does this matter? The event loop is not per-document, it's per-group-of-related-documents, no?
Where do you see this happening? Note that ES6 doesn't seem to tie the |
That all said, the problem of promises from unloading pages (or indeed script invocation in unloaded pages in general) not being specified very well and not being interoperably implemented is very real. See also https://bugzilla.mozilla.org/show_bug.cgi?id=1058695 where we ended up putting in some mitigations in Gecko that technically don't follow the spec, because technically following the spec requires leaking the world in common cases.... The problem is that there is no spec for this event loop stuff right now, and the spec for |
@plinss and myself discussed this issue as part of our May 2020 virtual f2f. Since the issue was raised and since agreed that there's no great way or reason to reject promises after unload we propose adding a new section to the Promises Guide. We should advise authors and users that promises may not resolve in circumstance that are considered 'not-normal' from the POV of user code execution. |
What is best practice regarding the handling of unresolved promises when a browsing context is closed (nav away, window close)? Should the promises be explicitly rejected, and if so, what Error object should be returned so the reason for the rejection can be determined? Or should the promises remain unresolved, with only a window.unload event generated? And if rejected, what is the timing of the rejection in relation to the unload event?
This relates to development of the Web NFC API: w3c/web-nfc#57
The text was updated successfully, but these errors were encountered: