Javascript: 在异步通信中继续循环之前等待 MIDI 设备的响应
Javascript: waiting for response from a MIDI device before continuing loop in asynchronous communication
我正在使用带有 Web MIDI 的 MIDI 协议 API 与 MIDI 设备通信。
每次等待响应或超时发送下一条消息时,我都想向此设备发送 MIDI 消息。通过
收到回复
我想要以下内容:
//gotMIDImessage will be called when the message is received
midiIn.onmidimessage = gotMIDImessage;
function gotMIDImessage(messageData) {
//Do something with the data
}
//send bunch of messages in a loop and wait for responce each time
function askDevice(){
for (var i=0;i<n;i++){
for (var j=0;j<m;j++){
midiOut.send([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
//wait for gotMIDImessage or timeout to continue and do something about the response hre
}
}
}
这是我的第一次尝试:
midiIn.onmidimessage = gotMIDImessage;
function gotMIDImessage(messageData) {
received.innerHTML=received.innerHTML+"<br>"+messageData.data;
return new Promise(resolve => {
setTimeout(() => {
resolve(1);
}, 100);
});
}
async function askDevice() {
var o = {'data': 'await'};
for (var i=0;i<5;i++){
for (var j=0;j<3;j++){
var res=await gotMIDImessage(o);
midiOut.send([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
}
}
}
显然是行不通的,因为await gotMIDImessage();
调用了函数gotMIDImessage()
,但是这个函数在收到消息时会自动触发。
我怎样才能做到这一点?
编辑:我也试过这个版本,但似乎不起作用
received=null;
midiMessage=null;
function gotMIDImessage(messageData) {
received=true;
midiMessage=messageData.data;
}
function sendWait(message){
received=false;
midiOut.send(message);
function waitForIt(){
if(!received){
setTimeout(function(){waitForIt()},1000);
}else{
alert("received");
}
}
return midiMessage;
}
function askDevice() {
var o = {'data': 'await'};
for (var i=0;i<5;i++){
for (var j=0;j<3;j++){
res=sendWait([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
}
}
}
res
始终为空,循环结束后我收到了所有 15 条消息
你可以这样做:
function awaitReply(msg, timeout = 5000) {
return new Promise((resolve, reject) => {
const gotMidiMessage = msg => {
midiIn.removeEventListener('midimessage', gotMidiMessage); // Removing the event listener again
resolve(msg);
};
midiIn.addEventListener('midimessage', gotMidiMessage);
midiOut.send(msg);
setTimeout(() => {
// Don't forget to remove the event listener
midiIn.removeEventListener('midimessage', gotMidiMessage);
/* Resolve the Promise anyway ... */
resolve(null);
/* ... OR reject it, but then you have to catch the error in the call */
// reject('Error message');
}, timeout);
});
}
async function askDevice() {
for (let i = 0; i < 5 ; i++) {
for (let j = 0; j < 3; j++) {
let res = await awaitReply([0xF0, 0x52, 0x00, 0x61, 0x09, 0x00, i, j, 0xF7]);
}
}
}
这是一个工作示例:
function awaitReply(msg) {
return new Promise(resolve => {
const gotMidiMessage = messageData => {
window.removeEventListener('midimessage', gotMidiMessage); // Removing the event listener again
resolve(messageData);
};
window.addEventListener('midimessage', gotMidiMessage);
midiOut.send(msg);
});
}
async function askDevice() {
for (let i = 0; i < 5 ; i++) {
for (let j = 0; j < 3; j++) {
let res = await awaitReply([0xF0, 0x52, 0x00, 0x61, 0x09, 0x00, i, j, 0xF7]);
// Logging your iterator variable which you want to send
console.log(res.detail[6], res.detail[7]);
}
}
}
const midiOut = {
send(msg) {
return setTimeout(() => {
let evt = new CustomEvent('midimessage', { detail: msg });
window.dispatchEvent(evt);
}, 1000);
}
};
askDevice();
我正在使用带有 Web MIDI 的 MIDI 协议 API 与 MIDI 设备通信。 每次等待响应或超时发送下一条消息时,我都想向此设备发送 MIDI 消息。通过
收到回复我想要以下内容:
//gotMIDImessage will be called when the message is received
midiIn.onmidimessage = gotMIDImessage;
function gotMIDImessage(messageData) {
//Do something with the data
}
//send bunch of messages in a loop and wait for responce each time
function askDevice(){
for (var i=0;i<n;i++){
for (var j=0;j<m;j++){
midiOut.send([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
//wait for gotMIDImessage or timeout to continue and do something about the response hre
}
}
}
这是我的第一次尝试:
midiIn.onmidimessage = gotMIDImessage;
function gotMIDImessage(messageData) {
received.innerHTML=received.innerHTML+"<br>"+messageData.data;
return new Promise(resolve => {
setTimeout(() => {
resolve(1);
}, 100);
});
}
async function askDevice() {
var o = {'data': 'await'};
for (var i=0;i<5;i++){
for (var j=0;j<3;j++){
var res=await gotMIDImessage(o);
midiOut.send([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
}
}
}
显然是行不通的,因为await gotMIDImessage();
调用了函数gotMIDImessage()
,但是这个函数在收到消息时会自动触发。
我怎样才能做到这一点?
编辑:我也试过这个版本,但似乎不起作用
received=null;
midiMessage=null;
function gotMIDImessage(messageData) {
received=true;
midiMessage=messageData.data;
}
function sendWait(message){
received=false;
midiOut.send(message);
function waitForIt(){
if(!received){
setTimeout(function(){waitForIt()},1000);
}else{
alert("received");
}
}
return midiMessage;
}
function askDevice() {
var o = {'data': 'await'};
for (var i=0;i<5;i++){
for (var j=0;j<3;j++){
res=sendWait([0xF0,0x52,0x00,0x61,0x09,0x00,i,j,0xF7]);
}
}
}
res
始终为空,循环结束后我收到了所有 15 条消息
你可以这样做:
function awaitReply(msg, timeout = 5000) {
return new Promise((resolve, reject) => {
const gotMidiMessage = msg => {
midiIn.removeEventListener('midimessage', gotMidiMessage); // Removing the event listener again
resolve(msg);
};
midiIn.addEventListener('midimessage', gotMidiMessage);
midiOut.send(msg);
setTimeout(() => {
// Don't forget to remove the event listener
midiIn.removeEventListener('midimessage', gotMidiMessage);
/* Resolve the Promise anyway ... */
resolve(null);
/* ... OR reject it, but then you have to catch the error in the call */
// reject('Error message');
}, timeout);
});
}
async function askDevice() {
for (let i = 0; i < 5 ; i++) {
for (let j = 0; j < 3; j++) {
let res = await awaitReply([0xF0, 0x52, 0x00, 0x61, 0x09, 0x00, i, j, 0xF7]);
}
}
}
这是一个工作示例:
function awaitReply(msg) {
return new Promise(resolve => {
const gotMidiMessage = messageData => {
window.removeEventListener('midimessage', gotMidiMessage); // Removing the event listener again
resolve(messageData);
};
window.addEventListener('midimessage', gotMidiMessage);
midiOut.send(msg);
});
}
async function askDevice() {
for (let i = 0; i < 5 ; i++) {
for (let j = 0; j < 3; j++) {
let res = await awaitReply([0xF0, 0x52, 0x00, 0x61, 0x09, 0x00, i, j, 0xF7]);
// Logging your iterator variable which you want to send
console.log(res.detail[6], res.detail[7]);
}
}
}
const midiOut = {
send(msg) {
return setTimeout(() => {
let evt = new CustomEvent('midimessage', { detail: msg });
window.dispatchEvent(evt);
}, 1000);
}
};
askDevice();