matthewmueller / joy

A delightful Go to Javascript compiler (ON HOLD)
https://mat.tm/joy
GNU General Public License v3.0
1.32k stars 35 forks source link

Improve Channels & Goroutines implementation #78

Open matthewmueller opened 6 years ago

matthewmueller commented 6 years ago

Originally we were planning on converting async/await into generators. However, as explained by @FlorianUekermann in #56, there's a good chance the async/await or generator implementation won't be enough:

If you are wondering why someone may want to use non-async event listeners in the first place, consider that JS has a well defined event flow (https://www.w3.org/TR/DOM-Level-3-Events/#event-flow), which gives you a lot of useful guarantees to work with (serial execution of event listeners, ordering of event listeners, bubbling, cancellation, etc.). All of that goes out the window once you are start using async.

Next steps:

UPDATE Alrighty yep, as suggested by @FlorianUekermann, the problem can be illustrated here: http://jsbin.com/ximexelepa/1/edit?html,js,output

FlorianUekermann commented 6 years ago

Edit: Nevermind. Your example is more fun :-). Me posting and your edit overlapped.

function receiveFromChannel() {
  return new Promise(resolve => setTimeout(() => resolve(" 2 "), 1));
}
var b = document.querySelector("button");
var p = document.querySelector("p");
b.addEventListener("click", async e => {
  p.textContent = " 1 ";
  var val = await receiveFromChannel(1);
  p.textContent += val;
});
b.addEventListener("click", async e => {
  p.textContent += " 3 ";
});

https://codepen.io/anon/pen/RxWBed/ Prints 1 3 2 for me instead of 1 2 3.

And just to demonstrate how quickly things get really messy without serial execution: Replace lines 8 and 9 with this:

p.textContent += await receiveFromChannel(1);;

https://codepen.io/anon/pen/rpOroG Prints 1 2

FlorianUekermann commented 6 years ago

Regarding GopherJS scheduling. Here is the scheduler logic in case you are looking for it: https://github.com/gopherjs/gopherjs/blob/444abdf920945de5d4a977b572bcc6c674d1e4eb/compiler/prelude/goroutines.go#L228 That part is pretty straightforward. Saving go routine state may be a bit more involved, I haven't had to look at that stuff yet.

matthewmueller commented 6 years ago

Some additional information: