sci 2023-04-12

Is deref not supported for Promesa promises?

(println (deref (p/promise 1)))

ERROR: No protocol method IDeref.-deref defined for type object: [object Promise]
  {:type :sci/error, :line 8, :column 16, :message "No protocol method IDeref.-deref defined for type object: [object Promise]"
Are the Promesa macros (`p/then` , etc) the only way to operate on the value? (I’m evaling this via Joyride, if that context is useful)

1

You could wrap promises with a deref implementation but it'll never be realized in the same synchronous context like your doing there.

If it's useful for you to be able to deref the promise in a later call, you could do something like this:

(extend-type js/Promise
  ICloneable
  (-clone [p] (.then p)))

(defn derefable-promise [v]
  (let [p (js/Promise.resolve v)
        resolved? (atom false)
        resolved-value (atom nil)
        res-p (-> p
                  (.then (fn [result]
                           (reset! resolved? true)
                           (reset! resolved-value result)
                           result)))]
    (specify
     res-p
     IPending
     (-realized? [_] @resolved?)
     IDeref
     (-deref
      [_]
      (if-let [res @resolved-value]
        res
        res-p)))))

please don't ;)

So in a do block, you couldn't print out the value in a blocking way:

(do
  (def p-fetch (js/fetch ""))
  (def p-json (.then p-fetch #(.json %)))
  (def p-iss (.then p-json
                    #(when-let [iss-position (.-iss_position %)]
                       (println :iss-position iss-position)
                       (js->clj iss-position :keywordize-keys true))))
  (def derefable-iss
    (derefable-promise p-iss))
  (println :derefed-iss @derefable-iss))

:derefed-iss #object[Promise [object Promise]]
;=> nil
But you could then later deref it:
@derefable-iss
:iss-position #js {:longitude -48.2400, :latitude 4.6248}
;=> {:longitude "-48.2400", :latitude "4.6248"}

@borkdude are you worried about polluting promise for other callers in the environment?

I think it will just add to the confusion of why it's not a blocking call, that's all

Right. Maybe promise-delay would be a better word. Or some better name

promesa must have some delay utility already though

Ah, promesa's delay gives you a literal time delay

yes, confusing name ;)

Oh wait, this is the sci channel šŸ˜† is specify even available in SCI like that?

@john The above example won't work in SCI

šŸ‘ 1

@sashton indeed, deref is not supported for promesa promises

this is not SCI-specific but true in general (for CLJS at least)

makes sense. thanks for confirming