我正在用node.js编写一些使用cylon.js的电机控件。我有一个伺服系统,当你给它一个角度时,它有一个回调函数。当它完成这个函数时,我想再读一次,给它一个新的角度,用回调来执行另一个reading...so,以此类推。
目前的代码是:
function ControlServo(servo, angleSensor){
robo.servo.angle(angleSensor.Read(), controlServo(servo, angleSensor));
}就像一刻秒一样被堆叠溢出。
发布于 2015-05-15 17:11:04
解决这个问题的一个更好的方法是使用timeout而不是递归。这将在下一个滴答中调用您的函数,这将永远不会溢出。
function ControlServo(servo, angleSensor){
robo.servo.angle(angleSensor.Read(), function() {
setTimeout(function() { ControlServo(servo, angleSensor)}, 0);
});
};您可以通过将timeout移动到servo.angle函数来缩短这一点,但是您可能需要它作为其他用途的回调。上面的方法不需要其他更改,因为回调只是设置超时。
另一个选项是setImmediate,它似乎将函数调用放在当前勾号的末尾,而不是下一个选项的开头。由于setTimeout总是会引入一个轻微的延迟,所以setImmediate可能会更快;但是,我不知道使用它可能会做什么其他的权衡,因为我自己也没有使用过它。
发布于 2015-05-16 17:35:49
用Cylon.js做你想做的事情是不可能的。is的内部“写”操作“回调”不是异步的,在移动机械地完成时不会被调用。它在写操作后立即被调用。赛昂只能将角值写入伺服,后者机械地移动喇叭以其最大的能力速度。如果它是一个缓慢的伺服,它可能需要2秒从0到180度,才能真正机械地完成。与此同时,赛昂已经打电话给回调了。之所以如此,是因为不需要做一些额外的工作,就无法以一种对所有伺服模型都一致正确的方式概括回调行为。
在约翰尼-5中,我们通过提供一个“完成时间”参数来实现速度控制。这是通过将到新角度的距离划分为在指定的“完成时间”内移动的步骤来完成的。这个过程的一个副作用是,约翰尼-五个伺服实例可以知道什么时候移动是机械完成,因为步骤较小,时间控制。因此,我们有一个“移动:完成”事件,该事件在任何时间移动完成时都会发出。
var servo = new five.Servo(9);
servo.on("move:complete", function() {
// we've arrived!
});
// change takes 500ms to complete
servo.to(180, 500);它可以很容易地与模拟传感器相结合:
var servo = new five.Servo(9);
var sensor = new five.Sensor({
pin: "A0", scale: [ 0, 180 ]
});
servo.on("move:complete", function() {
update();
});
function update() {
// change takes 200ms to complete
servo.to(sensor.value, 200);
}
update();甚至更简单:
var servo = new five.Servo(9);
var sensor = new five.Sensor("A0");
sensor.scale(0, 180).on("change", function() {
servo.to(this.value);
});https://stackoverflow.com/questions/30265046
复制相似问题