robot -递归回调- JavaScript

robot - Recursive Callback - JavaScript

本文关键字:JavaScript 回调 递归 robot      更新时间:2023-09-26

我正在使用cylon.js与node.js编写一些电机控制。我有一个伺服系统,当你给它一个角度时它有一个回调函数。当它完成该函数时,我想进行另一次读取,并给它一个新的角度,用回调进行另一次读取…等等。

当前代码为:

function ControlServo(servo, angleSensor){
robo.servo.angle(angleSensor.Read(), controlServo(servo, angleSensor));
}

在1/4秒内堆栈溢出

用Cylon.js做你想做的事是不可能的。Cylon.js内部的"写"操作"回调"不是异步的,当移动机械完成时不会被调用。它在写操作之后立即被调用。赛昂人只能将角度值写入伺服器,伺服器会以最大速度机械地移动喇叭。如果它是一个慢速伺服系统,从0到180度需要整整2秒的时间才能真正完成。同时,赛昂人已经回调了。这样做的原因是因为没有办法以一种对所有伺服模型始终正确的方式概括回调行为,而不做一点额外的工作。

在Johnny-Five中,我们通过提供"完成时间"参数实现了速度控制。这是通过将到新角度的距离划分为在指定的"完成时间"内移动的步骤来完成的。这个过程的一个副作用是,Johnny-Five伺服实例可以知道什么时候移动是机械完成的,因为步骤更小,时间可控。因此,我们有一个"move:complete"事件,在任何定时移动完成时发出。

<>之前var servo = new 5 . servo (9);伺服。On ("move:complete", function() {//我们到了!});//更改需要500ms才能完成伺服。(180、500);之前

可以很容易地与模拟传感器结合使用:

<>之前var servo = new 5 . servo (9);无功传感器=新五。传感器({引脚:"A0",刻度:[0,180]});伺服。On ("move:complete", function() {update ();});函数update() {//修改需要200ms才能完成servo.to(传感器。值,200);}update ();之前

更简单:

<>之前var servo = new 5 . servo (9);var sensor = new five.Sensor("A0");传感器。规模(0,180)。On ("change", function() {servo.to (this.value);});

解决这个问题的更好方法是使用timeout而不是递归。这最终会在下一次滴答时调用你的函数,它永远不会溢出。

function ControlServo(servo, angleSensor){
    robo.servo.angle(angleSensor.Read(), function() {
        setTimeout(function() { ControlServo(servo, angleSensor)}, 0);
    });
};

您可以通过将timeout移动到servo.angle函数来缩短它,但是您可能需要它作为其他用途的回调。上面的方法不需要其他更改,因为回调只是设置超时。

另一个选项是setImmediate,它似乎将函数调用放在当前刻度的末尾,而不是下一个刻度的开始。由于setTimeout总是会引入轻微的延迟,setImmediate可能会更快;然而,我不知道使用它可能会有什么其他的权衡,因为我自己也没有用过。