使用 defprotocol 创建 javascript 对象

Using defprotocol to create javascript object

假设我已经定义了一个协议

(defprotocol SubscriptionListener
  (onConnection [cid] "")
  (onUpdate [cid data] ""))

我正在与一个库进行交互,其中传入了一个具有此接口的 javascript 对象,如下所示

(js/somelib.connect url listener)

是否有使用定义的协议创建 javascript 对象的简单方法?

我已经尝试 reify 协议:

(js/somelib.connection "localhost" (reify SubscriptionListener
                                      (onConnection [cid] (println cid))
                                      (onUpdate [cid data] (println data))))

然而,这并没有提供与外部库兼容的对象。

谢谢

这里存在概念上的不匹配。 js 库已经期望定义的行为,但您想从 cljs 中自己定义它。 listener 应该是一个有 2 个方法的 js 对象,onConnectiononUpdate?然后,您需要在 cljs 中的 SubscriptionListener 和 js 中的常规对象之间进行一些翻译:

(defprotocol SubscriptionListener
  (on-connection [o cid])
  (on-update     [o cid data]))

(defn translator
  "Translates a cljs object that follows SubscriptionListener 
   into a js object that has the right mehods"
  [o]
  #js {:onConnection (fn [cid]      (on-connection o cid))
       :onUpdate     (fn [cid data] (on-update o cid data))})

(js/somelib.connection "localhost"
                        (translator (reify SubscriptionListener
                                      (on-connection [_ cid] (println cid))
                                      (on-update     [_ cid data] (println data))))

注意SubscriptionListener中的函数将符合协议的对象作为第一个参数。如果 cid 是服务器给你的某个 ID,而你尝试调用 (on-connection cid) 你会得到 Method on-connection not defined for integers.