背景
我正在使用<div class="container">
<svg height="100%" width="100%">
<text onclick="move(evt)" dx="0%" dy="50%" font-size="400">This is my Journey
</text>
</svg>
</container>
和rpio
作为我的应用程序的服务器一起工作,同时我希望能够使用raspberry
控制GPIO。到目前为止一切顺利,我只是一个初学者,我只是想在html页面上显示与GPIO相关的信息。
我想做什么
我想根据碰巧在服务器端进行操作的变量在客户端进行动态更改;换句话说,我希望每当此变量在服务器端更改其值时,javascript
会将其发送到客户端,以便我可以在{{1}内使用(显示)该变量的更新版本。 } 标签。
就我而言,我只想在页面上显示某个树莓针的高低。我使用一个socket.io
函数,该函数具有一个paragraph
循环,该循环在每次迭代时都打开和关闭某个引脚。
代码
我正在渲染主页'/',在这里我可以单击一个按钮以将发布请求发送到'/',然后渲染在blinkLed
的客户端部分位于的blinkLed页面以及在段落内要显示图钉状态的位置;当此类页面加载时,socketio在服务器端执行功能for
,以进行socketio
技巧,通过blinkLed()
函数将引脚置于高或低状态。一切正常。
注意,在函数rpio
中,每次在rpiowrite
循环中调用blinkLed()
时,我都会使用socket.emit
发出字符串“ high”或“ low”。>
app.js
rpiowrite
blinkLed.ejs
for
问题
var rpio = require('rpio')
var app = require('express')()
var http = require('http').createServer(app);
var io = require('socket.io')(http);
async function blinkLed(socket){
rpio.open(12, rpio.OUTPUT, rpio.LOW);
for (var i = 0; i < 5; i++) {
/* On for 1 second */
await rpio.write(12, rpio.HIGH);
await rpio.sleep(1);
await socket.emit('data','high')
/* Off for half a second (500ms) */
await rpio.write(12, rpio.LOW);
await rpio.msleep(500);
await socket.emit('data','low')
}
}
app.set('view engine', 'ejs');
app.get("/", function(req,res){
res.render('home')
})
io.on('connection', function(socket){
console.log('Blink Led Page');
blinkLed(socket)
});
app.post("/", async function(req,res){
res.render('blinkLed');
})
http.listen(3000,'0.0.0.0',function(){
console.log('server on')
})
函数运行良好;问题在于,自从for循环迭代开始以来就没有显示段落,而是仅在<script src="/socket.io/socket.io.js"></script>
<script>
function showParagraph(data){
return document.getElementById('p').innerHTML=data
}
var socket = io();
socket.on('data', function(data){
showParagraph(data)
})
</script>
<h1>BlinkLed</h1>
<p id='p'></p>
<a href='/'>Back</a>
迭代结束之后才显示某些内容。看来rpio
仅在最后一次迭代后才向客户端发出,然后仅在迭代的最后一个循环结束后才更改段落的值。我想在for循环的每次迭代中听听这些变化。反正有吗?
在此先感谢您提供任何帮助!
编辑:改进的问题
答案 0 :(得分:1)
您的rpio.write()
和rpio.sleep()
和socket.emit()
函数不会返回承诺。因此,将await
与它们一起使用根本没有用,因为await
仅在您等待诺言时才有用。
因此,您的for
循环只是一个同步for
循环,并且socket.emit()
可能实际上无法发送其数据,除非您给nodejs提供一些循环来处理它,这在{之后{1}}循环完成。
for
也可能实际上正在发送数据,但是数据以如此之快的速度到达客户端,您将永远没有机会看到屏幕更新,而您看到的只是最终更新
socket.emit()
函数阻止node.js Javascript线程。就像在the doc for your rpio libirary中所说的那样:“睡眠功能块,但是很少在这些简单的程序中做这件事。使用setInterval()/ setTimeout()循环代替
如果重要的话。” 嗯,这很重要。
因此,这里的一种解决方案是使用实际的非阻塞延迟,使每个人都有机会实际处理事物:
rpio.sleep()