Esta es mi primera pregunta sobre el desbordamiento de la pila, así que me gustaría saludar a todos. Mi pregunta hoy es la siguiente ...

Estoy tratando de usar un control deslizante jQuery UI para enviar valores a través de TCP / IP al puerto serie de Arduino.

Tengo la parte de comunicación prácticamente terminada (TCP y serial). El problema es que siempre que el usuario mueve el control deslizante, cada valor en el camino se envía uno tras otro muy rápidamente. Me gustaría retrasar el control deslizante para que envíe esos valores con un retraso de 100 ms entre cada paso.

Intenté usar 'setInterval' y 'clearInterval' sin éxito. Aquí está el código:

$(document).ready(function() {

    $( "#mySlider" ).slider({
        range: "min",
        min: 0,
        max: 180,
        value: 90,
        slide: function( event, ui ) {

        delayPan(ui.value);


        }   
});

$( "#total" ).val( $( "#mySlider" ).slider( "value" ) );

});



var timeOut;

function delayPan(vals) {

    $( "#total" ).val("$" +  vals );

    //the part below sends values to another PHP file in order to then send it using TCP/IP

    timeOut = setInterval(function()
    {

        $.get("insert_commands.php", {command: 39, parameter: 0, value: vals, number: 0}, 
        function(command,parameter,value,number){}, "json");

    }, 100);

    clearInterval(timeOut); 

}

Y para mayor claridad, aquí está el HTML del control deslizante en mi sitio web index.php:

<label for="total">ANGLE:</label>
<input type="text" id="total" style="border:0; color:#fa4b2a; font-weight:bold;">
</p>
<div id="mySlider"></div>

No estoy seguro de cómo solucionar esto. Soy bastante nuevo en javascript / jQuery. Podría retrasar la recepción en el socket Arduino o TCP, pero hay otros botones en el sitio web principal con diferentes retrasos configurados, por lo que debo hacerlo en jQuery si es posible.

Agradecería cualquier consejo.

Gracias Rob

1
RobZ 19 feb. 2020 a las 22:47

2 respuestas

La mejor respuesta

Felicitaciones por una pregunta bien escrita.

Creo que lo que estás viendo es una función Debounced or Throttled ( dependiendo de cuántas veces desee enviar el nuevo valor). En su caso, desea "regular" la función, es decir, limitar la frecuencia a la que se llama.

Entonces podríamos limitar la función de envío de posición cada 100 ms. De esa manera, incluso si la posición del control deslizante se cambia 25 veces en 100 ms, la solicitud AJAX solo se enviará una vez en esos 100 ms.

Lodash y Underscore le brindan posibilidades de Debouncing y Throttling de una función. Ben Alman también ofrece una pequeña biblioteca (ya no se mantiene) para Debouncing / Throttling. Solo puedo hablar por la biblioteca de Ben Alman, porque esa es la única que he usado.

He creado un Codepen para demostrarlo. Haga clic para verlo en acción. Aquí está el código relevante:

$(document).ready(function() {

  function delayPan(vals) {

    $( "#total" ).val("$" +  vals );

    //the part below sends values to another PHP file in order to then send it using TCP/IP
    $.get("insert_commands.php", {command: 39, parameter: 0, value: vals, number: 0}, function(command,parameter,value,number){}, "json");
 }

    const throttledDelayPan = $.throttle(1000, delayPan);

    $( "#mySlider" ).slider({
        range: "min",
        min: 0,
        max: 180,
        value: 90,
        slide: function( event, ui ) {
            throttledDelayPan(ui.value);
         }   
    });

  $( "#total" ).val( $( "#mySlider" ).slider( "value" ) );

});

Básicamente, declara una función que envía la solicitud AJAX. delayPan, en tu ejemplo.

Luego lo pasa a la función de aceleración de la biblioteca del acelerador ($.throttle), junto con un tiempo de aceleración (1000 ms en este caso, para demostrar el retraso).

La función del acelerador le devuelve otra función, que almacenamos en throttledDelayPan.

Finalmente, llamamos a throttledDelayPan en la devolución de llamada "slide" del control deslizante jQuery UI.

Como comentario aparte, tengo algunas recomendaciones:

  1. Le disuadiría de utilizar una solicitud GET si específicamente desea enviar datos a una API REST; sería más idiomático utilizar una solicitud POST.
  2. es posible que desee separar esto en dos funciones: la función estrangulada que envía la solicitud AJAX y la función que actualiza la pantalla "#total". De esa manera, podría actualizar continuamente la pantalla mientras reduce la cantidad de solicitudes AJAX que está enviando.
0
Bashu Naimi-Roy 19 feb. 2020 a las 20:39

Tienes dos soluciones para esto

1 no llame a la función de retraso desde el control deslizante, solo haga que el intervalo envíe siempre el valor actual del control deslizante cada 100 ms, también elimine el clearInterval(timeOut);

2 haga timeDelta para limitar la generación de las solicitudes de obtención

Me gusta esto https://codepen.io/vkv88/pen/PoqGzJE?editors=1000

0
Rkv88 - Kanyan 20 feb. 2020 a las 16:10