我将在本部分中开发Angular / Node应用程序,然后触发外部设备读取NFC卡,并将该信息发送给angular。但是,在我获得NFC信息之前,节点正在返回HTTP响应。
编辑以阐明更多要点
key.controller.js ,这是用户单击某个按钮请求NFC读取器读取某些卡之后,我在这里进入node.js的地方。
exports.requestKeyCode = async (req, res) => {
console.log('KeyController');
keyHelper.requestKeyCode().then( data =>{
console.log('Did I wait?')
res.send(data);
}).catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while retrieving Role."
});
});
}
keyYHelper 在此帮助器中,有一些额外的代码构成了发送给NFC读取器以读取NFC卡的电报
exports.requestKeyCode = async function() {
console.log('Entered requestDeviceInfo')
finalTelegram=newData.toString(16)+CHKS.toString(16);
this.ft=finalTelegram;
sendTelegramLoop(this.ft, 0).then( keyCode => {
return keyCode ;
})
}
在这里,希望一直将电报发送到NFC读取器,直到读取到有效的内容为止
async function sendTelegramLoop(telgeram, i ) {
setTimeout(() => {
hasRead = false;
global.comPort.write(telgeram, 'hex' ,function(err) {
hasRead = waitResponse().then(hasRead => {
if (err) {
return console.log('Error on write: ', err.message)
}
if (!hasRead){
sendTelegramLoop(telgeram, i++);
} else {
console.log('enteredExitRoutine');
return hasRead;
}
} );
})
}, 50)
}
在这里我将comPort设置为读取模式,并开始侦听NFC阅读器发送的电报,并过滤有效的响应电报。
async function waitResponse() {
console.log("waiting keyInfo");
rcvTelegram = global.comPort.read().toString('hex');
if (rcvTelegram.startsWith('a40101001c0a000') && rcvTelegram.length===56){
console.log("breaking telegram")
keyInfo = telegramHelper.breakTelegram(rcvTelegram) ;
console.log('Key Read='+ keyInfo);
return keyInfo;
}
}
基本上发生的是,在我将命令发送到设备以读取卡之后,nodeJS返回了HTTP请求。
我如何强迫它等待。
答案 0 :(得分:0)
在requestKeyCode()
中,您需要返回在其中创建的承诺,或者返回await
中的承诺。照原样,没有任何东西可以保证异步函数正在返回,因此它可以在您的sendTelegraphLoop()
实际完成之前解决。
exports.requestKeyCode = async function() {
console.log('Entered requestDeviceInfo')
finalTelegram=newData.toString(16)+CHKS.toString(16);
this.ft=finalTelegram;
return sendTelegramLoop(this.ft, 0);
}
或使用await
:
exports.requestKeyCode = async function() {
console.log('Entered requestDeviceInfo')
finalTelegram=newData.toString(16)+CHKS.toString(16);
this.ft=finalTelegram;
let keyCode = await sendTelegramLoop(this.ft, 0);
return keyCode;
}
此外,没有理由使用此内容:
.then(keyCode => {
return keyCode;
});
,因为它没有任何用处。这只是多余的代码。您已经解决了keyCode
的诺言,因此没有理由再用.then()
做出也解决成keyCode
的诺言。
然后sendTelegramLoop()
也有问题。您需要确保async
函数返回的Promise与函数内部的异步操作挂钩。 sendTelegramLoop()
中没有发生这种情况。
这里是解决sendTelegramLoop()
的问题:
function delay(t) {
return new Promise(resolve => setTimeout(resolve, t));
}
global.comPost.writeP = util.Promisify(global.comPost.write);
async function sendTelegramLoop(telgeram, i ) {
try {
// is this delay a hack? Why is it here
await delay(50);
hasRead = false;
await global.comPort.writeP(telgeram, 'hex');
hasRead = await waitResponse();
if (!hasRead) {
return sendTelegramLoop(telegeram, i++);
} else {
console.log('enteredExitRoutine');
return hasRead;
}
} catch(err) {
console.log('Error on write: ', err.message)
throw err; // propagate error back to caller
}
}
使用未在本地声明的更高范围的变量(如hasRead
)看起来很麻烦。无论如何,这个新的实现实际上将所有异步操作都挂接到async
函数返回的promise中,并返回一个解析为hasRead
值并可以递归工作的promise。
此外,waitResponse
似乎没有异步的任何内容,因此它只能是常规函数,而不是async
函数。