我目前有一个问题,不知道如何正确解决它。
我正在使用WebMidi API开发一个带有js的web应用程序。
我想在加载WebMidi之后将所有midi设备加载到下拉列表中。据我所知,我必须传递Webmidi的enable函数,一个回调函数:
WebMidi.enable(function (err) {
if (err) {
console.log("WebMidi could not be enabled.", err);
} else {
console.log("WebMidi enabled!");
}
});
我遇到的问题是,我不能在回调函数中引用类方法,但一旦启用WebMidi,我就必须调用该方法,该方法用所有midi输入填充下拉列表。
我的代码如下所示:
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!");
}
});
}
...
问题是fillDropdown()是在WebMidi完成激活之前调用的,此时数组是空的。我可以以某种方式引用回调函数中的类方法吗?
发布于 2021-01-30 14:54:05
WebMidi.enable
是一个异步函数,这意味着它允许您在启用WebMidi
之后指定要做什么。问题是你没有充分利用这个功能。
想象一下,你是开枪开始比赛的人:你的代码相当于射击,把你的眼睛从比赛中移开,但你仍然想知道比赛何时结束。如果你想在比赛结束后马上做点什么,最好看看比赛,对吧?
现在,构造函数启动WebMidi.enable
竞赛并立即尝试填充下拉列表。这不是你想要的--当比赛结束时,你想要填补掉下来的位置。
要解决您的问题,请让MidiListener.enable
接受一个回调函数,该回调函数将在完成WebMidi.enable
时执行,而不会出现错误。这将允许您在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();
}
});
}
现在,只有在this.fillDropdown
成功启动后才能执行WebMidi
。根据上述类比,构造函数现在表示“在WebMidi.enable
竞赛结束时填充下拉列表”。
另外,请注意,我使用了一个箭头函数来创建回调函数。这一点很重要,因为this
关键字与常规的function
-keyword函数一起使用时,其作用就像一个特殊的关键字。this
指的是什么,取决于它的名称--在您的例子中,这是WebMidi
代码中的某个地方。
为了避免这种情况,使用一个箭头函数,它将this
视为具有规则范围规则的正则变量。还有其他解决办法-- 这个答案解释得很好。。
https://stackoverflow.com/questions/65968515
复制相似问题