简体   繁体   English

JS - 在回调 function 内部调用 class 方法

[英]JS - Calling class methods inside of callback function

I'm currently having a problem and don't know how to solve it correctly.我目前遇到问题,不知道如何正确解决。

I'm developing a web application with js using the WebMidi API.我正在使用WebMidi API 开发一个带有 js 的 web 应用程序。

I want to load all midi devices into a dropdown after WebMidi is loaded.我想在加载 WebMidi 后将所有 midi 设备加载到下拉列表中。 As far as I understood it I have to pass the enable function of Webmidi a callback function:据我了解,我必须通过 Webmidi 的启用 function 回调 function:

WebMidi.enable(function (err) {
  if (err) {
    console.log("WebMidi could not be enabled.", err);
  } else {
    console.log("WebMidi enabled!");
  }
});

The problem I am having is I cannot reference class methods inside the callback function, but I have to call the method that's fills the dropdown list with all midi inputs, as soon as WebMidi is enabled.我遇到的问题是我无法在回调 function 中引用 class 方法,但是一旦启用 WebMidi,我必须调用用所有 midi 输入填充下拉列表的方法。

My code looks like this:我的代码如下所示:

class MidiListener{
    constructor(){
        this.enable();
        this.fillDropdown(Webmidi.inputs);
    }


    enable(){
        WebMidi.enable(function (err) {
            //Enable WebMidi
            if (err) {
              console.log("WebMidi could not be enabled.", err);
              window.alert("WebMidi is not supported by your Browser.")
            } 
            else {
                console.log("WebMidi enabled!");
            } 
        });
    }
...

The problem is fillDropdown() is called before WebMidi finished activating, and the array is empty at the time.问题是在 WebMidi 完成激活之前调用了 fillDropdown(),并且当时数组是空的。 Can I somehow reference class methods inside the callback function?我可以在回调 function 中以某种方式引用 class 方法吗?

WebMidi.enable is an asynchronous function , meaning it allows you to specify what to do once WebMidi is enabled. WebMidi.enable是一个异步 function ,这意味着它允许您指定启用WebMidi后要执行的操作。 The problem is that you're not using this functionality to full power.问题是您没有充分利用此功能。

Imagine you're the guy who shoots the gun to start a race: your code is the equivalent of shooting and turning your eyes away from the race but still wanting to know when the race ends.想象一下,您是开枪开始比赛的人:您的代码相当于开枪,然后将视线从比赛上移开,但仍想知道比赛何时结束。 If you want to do something right after the race ends, better look at the race, right?如果你想在比赛结束后立即做某事,最好看看比赛,对吧?

Right now, the constructor function starts the WebMidi.enable race and immediately tries to fill the dropdown.现在,构造函数 function 启动WebMidi.enable竞赛并立即尝试填充下拉列表。 That's not what you want - you want to fill the dropdown when the race ends.这不是你想要的——你想在比赛结束时填写下拉菜单。

To resolve your problem, make MidiListener.enable take a callback function that gets executed when WebMidi.enable is done without errors.要解决您的问题,请让MidiListener.enable接受一个回调 function ,当WebMidi.enable完成且没有错误时执行该回调。 This will allow you to do something right when WebMidi.enable finishes.这将允许您在WebMidi.enable完成时做一些正确的事情。

class MidiListener {
    constructor() {
        this.enable(() => {
            this.fillDropdown(WebMidi.inputs);
        });
    }

    enabledTest(err) {
        if(err) console.log("F");
        else console.log("Yeeee");
    }

    enable(callback) {
        WebMidi.enable(function (err) {
            //Enable WebMidi
            if (err) {
                // An error occured while starting WebMidi
                console.log("WebMidi could not be enabled.", err);
                window.alert("WebMidi is not supported by your Browser.")
            } 
            else {
                // WebMidi enabled successfully
                callback();
            } 
        });
    }

Now, this.fillDropdown will be executed only after WebMidi starts successfully.现在, this.fillDropdown只有在WebMidi启动成功后才会执行。 With the above analogy, the constructor function now says "fill the dropdowns when the WebMidi.enable race ends".通过上面的类比,构造函数 function 现在说“当WebMidi.enable比赛结束时填充下拉菜单”。

Also, note that I used an arrow function to create the callback function .另外,请注意,我使用箭头 function 来创建回调 function This is important because the this keyword, when used with regular function -keyword functions, acts like a special keyword.这很重要,因为this关键字在与常规function关键字函数一起使用时,就像一个特殊的关键字。 What this refers to depends on where it's called - which in your case is somewhere in WebMidi 's code. this指的是什么取决于它的调用位置 - 在您的情况下,它位于WebMidi的代码中。

To avoid that, use an arrow function which treats this like a regular variable with regular scoping rules.为避免这种情况,请使用箭头 function 将this视为具有常规范围规则的常规变量。 There are other workarounds too - this answer explains things very well .还有其他解决方法 -这个答案很好地解释了事情

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM