Although async/await is just syntax sugar over Promise, it has two advantages:
- emancipate programmers from chaining then or deep-nested callbacks.
- make async error handling easy. we can have a big try catch block at the beginning of our app, errors thrown from async/await functions will go up to the upper catch.
core.async solve first advantage as well, but I struggle to handle error in thrown in different functions.
After some search, I found async-error solve error handle issue with two macros go-try, <?. eg:
function fetchImg() {
return Promise.reject("img");
}
function fetchCss() {
return Promise.reject("css");
}
async function init() {
let img = await fetchImg();
let css = await fetchCss();
return img + css;
}
(async function() {
try {
let ret = await init();
console.log("ok = " + ret);
} catch (e) {
console.log("e = " + e);
}
}());
// e = img
(ns myapp.core
(:require [async-error.core :refer-macros [go-try <?]]
[cljs.core.async.interop :refer-macros [<p!]]))
(defn <fetch-img []
(go-try
(<p! (.reject js/Promise "img"))))
(defn <fetch-css []
(go-try
(<p! (.reject js/Promise "css"))))
(defn init []
(go-try
(try
(let [img (<? (<fetch-img))
css (<? (<fetch-css))]
(println "ok = " (+ img css)))
(catch js/Error e
(println "err = " e)))))
(init)
err = #error {:message Promise error, :data {:error :promise-error}, :cause img}