如何使浏览器返回的对象全局可用,然后将函数设置为 属性?

How do I make an object returned by the browser globally available then set a function as a property?

我正在尝试访问 ClojureScript 项目中的 MIDI 输入,在 JS 中使用类似的东西:

if (navigator.requestMIDIAccess) {
 console.log('WebMIDI is supported in this browser.');
 navigator.requestMIDIAccess().then(onMIDISuccess, onMIDIFailure);

我想出了如何让它与 Promesa 库一起工作! capability...然而,JS中的returned对象有一个MIDI输入列表,需要设置一个函数作为'onmidimessage'属性输入的值你关心的。在 JS 中,它看起来像这样:

function onMIDISuccess(midiAccess) {
  var inputs = midiAccess.inputs;
  for (var input of midiAccess.inputs.values()) {
  input.onmidimessage = getMIDIMessage;
 }}

在JS中,只要有MIDI信息进来,getMIDIMessage就会被调用。如何设置一个函数作为'onmidimessage'属性的return值的值navigator.requestMIDIAccess 以便正确调用它?

我试过套装的变体!并得到并且都不起作用。也许我在全局范围内设置 'midiAccess' 对象不正确或没有正确设置...不确定。

更新:克服尴尬并添加我的尝试:

  (ns miditest.midi)

  (defn onMIDISuccess [midiAccess]
    (let [inputs (.values (.-inputs midiAccess))]
    (js/console.log (first inputs))))

  (defn onMIDIFailure []
    (js/console.log "this browser does not support WebMIDI."))

  (defn getMIDIMessage [message]
    (let [command (first (.data message))
        note (nth (.data message) 1)
        velocity (nth (.data message) 2)]
    (js/console.log (str command note velocity))))

  (defn checkmidi []
    (-> (.requestMIDIAccess js/navigator)
      (.then #(onMIDISuccess %))
      (.catch #(onMIDIFailure))
      (.finally #(js/console.log "cleanup"))))

I'm not sure the .catch will work as I'm not sure how to get .requestMIDIAccess to fail.

您可以使用 set!.

(defn getMIDIMessage [message]
  ...)

(defn onMIDISuccess [midiAccess]
  (-> midiAccess
      .-inputs
      (.forEach (fn [input key]
                  (set! input -onmidimessage getMIDIMessage)))))