Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Thanks for sticking your neck out and providing code to back up your argument! I'm going to refute it quite heavily below, and just wanted to clarify that it's all down to the particular semantics of Javascript and browser form APIs. Since you say you're not familiar with the language, it's absolutely fine that you wouldn't have known this, so this isn't a personal attack against you; just a clarification for you and hopefully others about why this wouldn't work :)

    formStatus.appendChild(spinner);
    succ = submitForm();
    formStatus.removeChild(spinner);
You're solving an easier problem: synchronous form submission.

The code in the article (which is Javascript, the "J" in "AJAX"; although there's some stuff in the final example which I assume is "JSX") is solving asynchronous form submission (the "A" in "AJAX").

In general, Javascript programs work by attaching handlers to events. Events happen asynchronously, i.e. triggering an event like `submitForm` will push that event (or, equivalently, its handlers) to a queue, then carry on with the next instruction. Blocks of Javascript code, like event handlers, are also guaranteed to run from start to finish before anything else happens.

This means that your algorithm cannot work, even as pseudocode. Calling `submitForm()` will simply queue up that event. We won't be given the result of the form submission (which you call `succ`) since, according to the semantics, the form hasn't actually been submitted yet. This breaks all of the subsequent code.

What about faking it? We could try setting `succ = null`, and use an event handler on the form submission to overwrite this value. Then we can put a loop like `while (succ == null) { sleep(1); }` to wait until that handler gets run. Except Javascript doesn't have `sleep`, so we'd need to use a busy-loop instead like `while (succ == null) {}`. That will use 100% CPU while we're waiting, which is pretty horrible. Yet it also won't work! Remember that Javascript executes one block of code (like an event handler) before it starts on another (this is important to prevent horrible race conditions). In this case, the value of `succ` will never get overwritten, since the event handler can't be run until the current block has finished; yet the current block will never finish, since it's running an infinite loop!

Also, when I say that nothing else happens until a code block has finished, this includes interactions with the page. Hence even if it were possible to implement your algorithm in Javascript (which, as detailed above, I think is impossible), the entire page would freeze while we're waiting for the form submission to take place (possibly including the spinner, which defeats the whole point of having one). In browsers which don't use separate processes per tab, this might make the whole browser freeze.

Also note that your code still doesn't deal with the possibility of multiple executions, which is what the whole post was about. Even if it were possible to make your algorithm run in a browser, and even if that didn't cause the whole browser to hang, clicking the button multiple times would still cause multiple spinners to appear, which is exactly the problem that the original post was trying to avoid ;)



Thanks for the explanation; this really helps readers of the article who are not totally familiar with the environment. I've done UI programming before, but not in JS, which has a similar feel. Async certainly makes things more interesting, but I maintain that it's still possible to make the code simple and without needing an explicit state machine, by essentially adopting the "continuation passing style"[1] exhibited in the first example and adding guards to make the sections execute in order; one of the other comments here mentioned disabling buttons after they're clicked and not enabling them again until whatever async operation they started has finished, and that's the usual solution to problems like this. Besides acting like a "gate" on the code to prevent the state problems described in the article, the obvious disablement also informs the user to not click again.

[1] https://en.wikipedia.org/wiki/Continuation-passing_style


You could have been more generous and assumed they meant `succ = await submitForm();`


I've actually never used any async/await stuff, so I didn't know that's what it's for. All that stuff appeared in JS (and elsewhere) after I stopped doing Web dev. These days I mostly write Haskell, which AFAIK doesn't need all of that async/await/promise stuff because its already covered by laziness.


`await` is essentially syntactic sugar that means "wrap everything after this in a callback to be executed after this function does something asynchronously."


I see. That would presumably still have the problem of multiple spinners, as I mentioned at the end of my original comment?


Yes. You'd want to guard against this running more then once, probably by disabling the button until the submit finished.




Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: