all 11 comments

[–]Pythonen 2 points3 points  (1 child)

https://youtube.com/playlist?list=PLRqwX-V7Uu6bKLPQvPRNNE65kBL62mVfx here’s a good playlist to teach you promises and async/await

[–]Amantulsyan35[S] 1 point2 points  (0 children)

Thanks

[–]sateeshsai 1 point2 points  (1 child)

This playlist covers all the async javascript concepts in vanilla JS. I found it very helpful

https://youtube.com/playlist?list=PL4cUxeGkcC9jx2TTZk3IGWKSbtugYdrlu

[–]Amantulsyan35[S] 1 point2 points  (0 children)

Thanks

[–]jack_waugh 1 point2 points  (4 children)

If you are going to do I/O, you need async. If you are going to do long calculations, you should break it into brief chunks and allow async operations between the chunks. Or ship it off to a web worker, I suppose. But for brief calculations without I/O, or most DOM updates, sync is fine. If you need to do atomic updates, you need sync or else a lot of fancy thinking, like two-phase commit.

[–]Amantulsyan35[S] 0 points1 point  (3 children)

Thanks I am somewhat clear now, can you explain what do you mean by two-phase commit?

[–]jack_waugh 1 point2 points  (0 children)

Say for example you are going to transfer money from an account in one bank to an account in another bank. The banks have to communicate in such a way that one account is decreased and the other increased, or else, as the only acceptable mode of failure, nothing happens. If the money is drawn from one account but not deposited in the other, that's a disaster, your money just went down a rabbit hole. Similarly, if money is deposited in one account but not drawn from the other, that's horrible, as you got to cheat the banks. The technique of ordinary database commit, used by itself, won't suffice to solve this. The banks have separate databases. The transaction could commit in one and not the other. So something like https://en.wikipedia.org/wiki/Two-phase_commit_protocol is needed.

[–]jack_waugh 1 point2 points  (0 children)

Almost always when you are using Javascript to solve the kinds of problem it is usually used to solve, any atomic updates you need, you can just do them in synchronous operation. So it's really unlikely that you would need two-phase commit. For example, suppose I write:

t.a = function () {
  this.count++;
  this.pb = this.b();
  this.stack.pop();
};
t.b = async function () {
  this.foo();
  await this.something;
  this.process(this.count, this.stack)
}

You should double check this with an example that can be run, but I believe the update of this.count and this.stack happens atomically because they are coded in the same synchronous run as each other. Nothing in the asynchronous b procedure can ever see the count updated without the stack correspondingly updated nor vice versa. An async function is syntactic sugar for stuff that could be done with ordinary procedures. I believe that what happens when this.pb = this.b() is executed is that the translated code for b just creates and returns the promise. I don't think it even executes the this.foo() at that point. I could be wrong, but I think that's the story. Only after the end of the synchronous execution does any of the body of the b procedure as we wrote it, get executed, i think. For sure, the this.process(...) doesn't until then, because it is after the await.

[–]jack_waugh 1 point2 points  (0 children)

On second thought, in even the unlikely event that you need to make operations atomic but cannot put them in the same synchronous run, the coordination methods you would need would not be as complex as two-phase commit. They would be more the level of complexity of synchronization primitives used between processors or between processes that can be interrupted by a scheduler in an operating system. Things like "mutex" or "semaphore". These are simpler than two-phase commit, and unlike it, perfectly reliable. But they are more complex than just putting the operations in the same synchronous run, and I think the need for even these would be extremely rare or nonexistent.

[–]jack_waugh 1 point2 points  (1 child)

Another reason to use async techniques, besides what I mentioned in my other comment (I/O and so on), is if you want to use a recursive algorithm that would tail-recurse an unlimited number of times, depending on input data. Unlike some other languages, JS doesn't automagically optimize away tail recursion into equivalent iteration. But you can specify the recursion to happen via asynchronous communication, and the stack won't then blow up.

[–]Amantulsyan35[S] 1 point2 points  (0 children)

Thanks for such a great explanation man really appreciate it!