nbb

Gregory Bleiker 2026-04-09T16:58:16.140939Z

I'm trying to figure out promises on the repl: The example below once calls load-file and once I paste the code. They behave differently. I probably have to tell the pasted version to await, but I can't figure out how.

user=> (ns user
  #_=> (:require [promesa.core :as p]))
  #_=>
  #_=> (def kv-promise (js/Deno.openKv "something"))
  #_=>
  #_=> (-> kv-promise
  #_=>     (p/then (fn [kv]
  #_=>               (prn "Got KV instance")
  #_=>               (let [result (.set kv #js["test"] #js{:a "b"})]
  #_=>                 (prn "Set returned:" (type result))
  #_=>                 result)))
  #_=>     (p/then (fn [set-result]
  #_=>               (prn "Set completed with result:" set-result)
  #_=>               (println "done")
  #_=>           set-result))
  #_=>     (p/then (fn [_] (println "did we get here?")))
  #_=>     (p/catch (fn [err]
  #_=>                (prn "Error occurred:" err)
  #_=>                (prn "Error stack:" (.-stack err)))))
#object[Lt user]
#'user/kv-promise
#<Promise[pending:23]
here's the load-file version:
user=> (nbb.core/load-file "kvtest.clj")
"Got KV instance"

"Set returned:" #object[Promise]

"Set completed with result:" #js {:ok true, :versionstamp "00000000000000190000"}

done

did we get here?

nil

Gregory Bleiker 2026-04-13T17:09:40.053839Z

@borkdude works, awesome! Sorry for the testing delay.

Gregory Bleiker 2026-04-13T17:10:47.861429Z

I find working with promises the hardest part at the moment.. is there anything in clj-kondo that helps, like spotting un-awaited promises?

borkdude 2026-04-13T17:52:25.726899Z

Actually you can now use async/await in SCI and thus in nbb, which makes writing async code easier

borkdude 2026-04-13T17:53:01.229539Z

docs: https://github.com/babashka/sci/blob/master/doc/async-await.md

👍 1
Gregory Bleiker 2026-04-13T19:09:20.903539Z

Will this work with any kind of promises, like the one from deno above?

borkdude 2026-04-13T19:10:40.957779Z

good question. I expect Deno doesn't have a custom Promise, just a js/Promise, but SCI might not have accounted for mixing with the custom promesa promesas (thenable). I'll test

borkdude 2026-04-13T19:11:46.971649Z

seems to work:

user=> (def p (p/resolved 1))
#'user/p
user=> (defn ^:async my-fn [] (let [x (await p)] (inc x)))
#'user/my-fn
user=> (my-fn)
#<Promise 2>

borkdude 2026-04-09T18:51:30.941469Z

I think the problem is that nbb isn't aware of promesa's custom promise type. Can you try to convert it to a platform promise and then see if the behavior is still different?

borkdude 2026-04-09T18:52:02.656019Z

nbb has a couple of (instance? js/Promise x) checks and it should try to check for .then instead

borkdude 2026-04-09T18:53:50.830999Z

Just wrap it in (js/Promise.resolve ...)

borkdude 2026-04-09T18:54:11.059249Z

if that fixes the issue, please make an nbb github issue and I'll make a new release with the fix

borkdude 2026-04-09T19:28:18.148509Z

Already pushed out a new version, please try it

😮 1
Gregory Bleiker 2026-04-09T20:15:17.537139Z

@borkdude could you check if the jsr publish is broken? The version there is still 1.3.205

borkdude 2026-04-09T20:31:03.490019Z

try again