如何让含嵌套回调的regRead8函数返回wire.read获取的值?
异步I2C寄存器读取函数返回结果的实现方案
原代码与需求
你提供的代码如下:
regRead8: function(address){ wire.write([address & 0xFF, address >> 8], function(err){ if (!err == null) { console.log(err) } }) wire.read(1, function(err, res){ if (!err == null) { console.log(err) } }) }
regRead8 的核心逻辑是:
- 向FPGA写入目标寄存器地址
- 从该寄存器读取1字节数据
需求是让 regRead8 能返回 wire.read() 回调中的 res 值,供其他函数调用使用,且必须保留库要求的回调形式。
关键问题说明
原代码存在逻辑漏洞:wire.write 和 wire.read 是并行执行的,没有保证写入完成后再执行读取,这会导致读取操作可能在地址写入前执行,无法得到正确结果。所以首先要保证两个操作的顺序,再解决返回值的问题。
解决方案
方案1:用Promise封装(推荐,支持async/await)
将函数改为返回Promise,在异步操作完成后通过resolve返回结果,reject传递错误:
regRead8: function(address){ return new Promise((resolve, reject) => { // 先执行地址写入,写入成功后再执行读取 wire.write([address & 0xFF, address >> 8], function(err){ if (err) { console.log(err); reject(err); return; } // 写入完成后执行读取操作 wire.read(1, function(err, res){ if (err) { console.log(err); reject(err); return; } resolve(res); // 返回读取到的字节数据 }); }); }) }
调用方式(使用async/await):
async function getTargetRegister(registerAddr) { try { const registerValue = await regRead8(registerAddr); return registerValue; // 直接返回结果给上层函数 } catch (error) { console.error('寄存器读取失败:', error); throw error; // 向上层传递错误 } }
方案2:添加自定义回调参数
如果不想使用Promise,也可以给regRead8增加一个回调参数,将结果通过回调传递:
regRead8: function(address, callback){ wire.write([address & 0xFF, address >> 8], function(err){ if (err) { console.log(err); callback(err, null); return; } wire.read(1, function(err, res){ if (err) { console.log(err); callback(err, null); return; } callback(null, res); // 第一个参数为错误,第二个为结果 }); }) }
调用方式:
// 在其他函数中调用 function someFunction() { regRead8(0x01, function(err, value) { if (err) { console.error('读取错误:', err); return; } // 在这里使用读取到的value console.log('寄存器0x01的值:', value); }); }
内容的提问来源于stack exchange,提问作者iBus
相关产品推荐
相关产品推荐

