问题
An example :
var list = readHugeList();
var nextListItem = function() {
var item = list.pop();
if (item) {
setTimeout( nextListItem, 0);
// ^^^^^^^^ this line
}
};
How does use of setTimeout prevent potential stackoverflow here? I understand concept of event queue as well as stack, but I'm having difficulty connecting the two.
回答1:
Set timeout would not cause stack overflow, because it is asynchronous. It will just put the callback to the event queue and not block the execution.
In the first case:
setTimeout just puts the callback to event queue and the parent function exits after without busying the stack.
Even though the timeout is 0 ms, it will be called in the next event loop, thus not blocking the code in execution
var nextListItem = function() {
var item = list.pop();
if (item) {
setTimeout( nextListItem, 0);
}
};
In the second case:
Parent call the child function putting new entry into stack, even though the parents is not cleared from the stack.
Eventually more recursive calls would blow the stack.
var nextListItem = function() {
var item = list.pop();
if (item) {
nextListItem();
}
};
回答2:
Think of setTimeout(, 0)
to schedule a function to run after this one terminates. nextListItem()
will not be recursively called, but called again by the JS environment.
If you do var r() = function() { r(); };
the function calls itself and will overflow the stack. If you do var r() = function() { setTimeout(r, 0); };
then r()
will be scheduled to run after r()
terminates and it will run forever.
The is a reason to use setTimeout(, 0)
instead of while
or for
to loop over the list. It allows the browser to process other events before the next call to nextListItem
. If the list is long, this avoids blocking the browser for a long time. On the other hand, if nextListItem
is manipulating the DOM, it is much slower than doing it in one slew.
来源:https://stackoverflow.com/questions/37592940/how-does-settimeout-prevent-potential-stackoverflow