What happens to a Web Worker if I close the page t

2019-01-23 05:40发布

问题:

Let's say I have a page called Main.html that creates a web worker. If I close the Main page by changing window.location, would the web worker be terminated or would the web worker be still running?

How does Firefox or Chrome choose to "handle long-running Worker tasks after the page has closed"? If the worker's task is to send a very quick POST request, for this case, does the browser terminate the worker immediatly after the page is closed or does the browser allow the worker to finished its POST request?

回答1:

Short answer: This behavior is implementation-defined, and the specification allows behavior to vary from browser to browser (or vary situationally within one browser), except for some guarantees about event queues.

Long answer:

Closing or navigating away from a page causes the browser to discard the page's document:

User agents may discard top-level browsing contexts at any time (typically, in response to user requests, e.g. when a user closes a window containing one or more top-level browsing contexts).

The W3C Worker spec says that a Worker has a "list of Documents". For workers spawned by a web page with a window (i.e., not a Worker), the list consists of the single Document of the page that spawned it. The spec goes on to say:

Whenever a Document object is discarded, it must be removed from the list of the worker's Documents of each worker whose list contains that Document.

And also that:

A worker is said to be a permissible worker if its list of the worker's Documents is not empty.

This definition is used later:

Closing orphan workers: Start monitoring the worker such that... no later than it stops being a permissible worker, worker global scope's closing flag is set to true.

Finally, the "closing flag" prevents new activity on the worker:

Once the WorkerGlobalScope's closing flag is set to true, the event loop's task queues must discard any further tasks that would be added to them (tasks already on the queue are unaffected except where otherwise specified). Effectively, once the closing flag is true, timers stop firing, notifications for all pending asynchronous operations are dropped, etc.

Any old, long-running activity still running may be halted by the browser, but does not have to be:

User agents may invoke the "kill a worker" processing model on a worker at any time, e.g. in response to user requests, in response to CPU quota management, or when a worker stops being an active needed worker if the worker continues executing even after its closing flag was set to true.

Thus, the W3C specification allows for the worker to continue running, but does not allow it to handle any further events (worker messages, timers, network communication callbacks, etc.). A particular browser may choose to kill the worker at any time for performance reasons. The way that each browser chooses to handle long-running Worker tasks after the page has closed is outside the scope of the specification; it is implementation-defined. You should not depend on this behavior one way or the other: you should tolerate immediate termination, and should also tolerate any long-running tasks not immediately terminating with the closure of the page.

Shared Workers are subject to the exact same rules, except that their list of Documents includes all Documents currently using them, so their closing flag is set only after all the Documents have been closed.