Reputation: 133
The following JavaScript code emulates retrying an HTTP request as often as the user presses the OK button on a window.alert
. It can be seen that the stack trace dumped to the console increases in length linearly with the number of times the request retried.
To run this, use chromium --user-data-dir=/tmp/"$(uuidgen -r)" --disable-web-security
and navigate to an HTML file that just contains the bare minimum <html>
<body>
and <script>
tags. Disabling web security is required for the HTTP request to succeed, otherwise the default CORS policy will block it.
Basically, the question is: how can this linear stack creep be prevented?
function f() {
console.log("C");
fetch('http://swapi.co/api/films').
then(function (response) {
console.log("D");
return response.json();
}).then(function (response) {
console.log("E");
console.log(response);
console.trace();
window.alert("more?");
f();
});
}
function ignition() {
console.log("B");
f();
}
console.log("A");
window.onload = ignition;
Upvotes: 0
Views: 57
Reputation: 133
Found a solution; it's not ideal as it involves setInterval
but it's workable and avoids stack creep. It can only do straight retry; this solution cannot maintain any extra state between invocations of the queued functions, though it wouldn't be that hard to add.
const self_queue = [];
function self_append(fun) {
self_queue.push(fun);
}
setInterval((function() {
if (self_queue.length > 0) {
const fun = self_queue.shift();
fun(fun);
}
}), 100);
function ajax(url, fun) {
self_append((function (self_fun) {
// ...
// do the HTTP fetch, on success call fun(json)
// on retry, do:
self_append(self_fun);
// ....
}));
}
Upvotes: 1