Skip to content

Instantly share code, notes, and snippets.

@shaunlebron
Last active July 28, 2018 07:58
Show Gist options
  • Save shaunlebron/d231431b4d6a82d83628 to your computer and use it in GitHub Desktop.
Save shaunlebron/d231431b4d6a82d83628 to your computer and use it in GitHub Desktop.
es7 vs core.async

Comparing ES7 and core.async

ES7 core.async
async function() {...} (fn [] (go ...))
await ... (<! ...)
await* or Promise.all(...) (doseq [c ...] (<! c))

async

Calling foo returns a promise receiving value 1:

async function foo () {
  return 1;
}

Calling foo returns a channel receiving value 1:

(defn foo []
  (go 1))

await

bar is parked until foo has finished:

async function bar() {
  await foo();
}

bar's go-block is parked until foo has finished:

(defn bar []
  (go
    (<! (foo))))

await all

baz waits for foo and bar to complete:

async function baz() {
  await Promise.all([foo(), bar()]);
}
(defn baz []
  (go
    (doseq [c [(foo) (bar)]]
      (<! c))))
@alex-dixon
Copy link

This is great! Thanks.

What would your translation be for this?

const main = async (args) => await getStuff(args)

main([42, 43]).then(stuff => console.log(stuff)).catch(e => console.error(e))

@rjungemann
Copy link

@alex-dixon Your second line can become:

try {
  const stuff = await main(42, 43);
  console.log(stuff);
} catch (e) {
  console.error(e);
}

Here's my stab at it:

(defn main [args]
  (go (<! (get-stuff args)))

(try
  (let [stuff (go (<! (main 42 43))]
    (prn stuff))
  (catch Exception e (prn e)))

@jmlsf
Copy link

jmlsf commented Mar 15, 2018

@shaunlebron Thanks for this. One important difference: uncaught exceptions in core.async get eaten and will not pass the go-block boundary. You must be sure to catch them yourself and come up with your own error handling convention. Async/await converts uncaught exceptions into a rejected promise, so you don't have to worry about it.

@zonzujiro
Copy link

zonzujiro commented Mar 29, 2018

Hi! Great gist! Thank you.

And I have a question :) Promise.all will return array with results. And doseq will call <! on each channel and you will get data one-by-one, right?

But what if I need both results at the same time? Is there any way to get them?

I tried to resolve this with async/merge, but it will return a channel, from which I must get values by one at the time to.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment