JavaScript如何实现轮询API播放MIDI音符时仅播放唯一值无重复
解决方案
实现逻辑很简单,新增一个变量存储上一次触发播放的温度值,每次轮询拿到新的返回结果后先做值对比,只有温度发生变化时才触发音符播放即可,不需要用到你查询的filter或者onlyUnique相关能力。
另外注意原代码存在一处拼写错误:判断温度等于12的条件里将temperature错写为temparature,会导致12这个取值的判断失效,下面的修改代码已经修正了这个问题。
修改后的完整代码
let easymidi = require("easymidi") let output = new easymidi.Output("mindiPort", true) let interval; const fetch = require("node-fetch"); // 新增:存储上一次触发播放的温度值,初始值设为温度范围外的-1保证首次一定触发 let lastTemperature = -1 let sendNote = (noteValue, duration) => { output.send("noteon", noteValue) setTimeout(()=> { output.send("noteoff", noteValue) }, duration); } const api_url = 'https://www.placeholder_url.com?timeout=1000' setInterval(() => fetch(api_url) .then((response) => { return response.json(); }) .then((myJson) => { const currentTemp = myJson.temperature // 和上一次温度对比,相同就直接跳过 if (currentTemp === lastTemperature) return // 温度有变化才执行后续逻辑 let note; if (currentTemp == 0) { note = 24; } else if (currentTemp == 2) { note = 25; } else if (currentTemp == 4) { note = 26; } else if (currentTemp == 6) { note = 27; } else if (currentTemp == 8) { note = 28; } else if (currentTemp == 10) { note = 29; } else if (currentTemp == 12) { note = 30; } else if (currentTemp == 14) { note = 31; } else { note = 32; } let noteValue = { note: note, velocity: 100, channel: 1 } sendNote(noteValue, 500) // 更新存储的上一次温度值 lastTemperature = currentTemp }), 5000);
核心修改点说明
- 新增全局变量
lastTemperature,初始值设为-1(不在你的温度取值0-16范围内),确保第一次请求返回的温度一定会触发播放 - 每次拿到API返回的温度后,先和
lastTemperature做全等对比,值相同就直接终止本次后续逻辑 - 只有温度值发生变化时,才执行音符映射、播放操作,同时将
lastTemperature更新为当前的温度值,用于下一次轮询的对比校验
内容的提问来源于stack exchange,提问作者Leo Optimo II
相关产品推荐
相关产品推荐

