Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

197
Vistas
How can I create a simple loading animation while a function is running?

I'm trying to create a simple loading animation for an arbitrary function in JQuery Terminal. I know that JavaScript is single threaded and synchronous, but are there any workarounds?

I've seen the JQuery progress bar animation example, but I'm not sure how I can run an animation similar to that while another function runs on the background. Could I potentially use async and await functions?

Below is a simple reproducible example:

var terminal = $('#terminal').terminal( function(command, term) {
                    arbitrary_function();
                    let i = 0;
                    let loading_animation = ['[LOADING     ]', '[LOADING .   ]', '[LOADING ..  ]', '[LOADING ... ]', '[LOADING ....]']
                    (function loop() {
                        terminal.set_prompt(loading_animation[i]);
                        timer = setTimeout(loop, 550);
                        i = ((i + 1) % 5);
                    })();   
                }

Ideally, I'd want everything below arbitrary_function() to run until arbitrary_function() is done. How can I possibly do that in JavaScript?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

@Wyck is right you can use Web Workers for this if your arbitrary_function do long computation, here is example how to do this using Comlink library

var terminal = $('body').terminal(function() {
  const promise = arbitrary_function();
  // we don't want interactivity, but want prompt to be visible
  terminal.pause(true);
  let i = 0;
  const loading_animation = [
    '[LOADING     ]',
    '[LOADING .   ]',
    '[LOADING ..  ]',
    '[LOADING ... ]',
    '[LOADING ....]'
  ];
  let stop = false;
  const prompt = terminal.get_prompt();
  (function loop() {
      terminal.set_prompt(loading_animation[i]);
      if (!stop) {
          timer = setTimeout(loop, 550);
      } else {
          // clear the animation
          terminal
              .echo(loading_animation[i])
              .set_prompt(prompt)
              .resume();
      }
      i = ((i + 1) % 5);
  })();
  promise.then(function() {
    // long calculation is done
    stop = true;
  });
});

function arbitrary_function() {
  return worker.longTask();
}

const worker = Comlink.wrap(fworker(function() {
  importScripts("https://cdn.jsdelivr.net/npm/comlink/dist/umd/comlink.min.js");

  Comlink.expose({
    longTask() {
      let i = 3000000000;
      while (i--) {
        Math.pow(2, 100000000);
      }
    }
  });
}));

// function to worker
function fworker(fn) {
    var str = '(' + fn.toString() + ')()';
    // ref: https://stackoverflow.com/a/10372280/387194
    var URL = window.URL || window.webkitURL;
    var blob;
    try {
        blob = new Blob([str], { type: 'application/javascript' });
    } catch (e) { // Backwards-compatibility
        const BlobBuilder = window.BlobBuilder ||
              window.WebKitBlobBuilder ||
              window.MozBlobBuilder;
        blob = new BlobBuilder();
        blob.append(str);
        blob = blob.getBlob();
    }
    return new Worker(URL.createObjectURL(blob));
}
<script src="https://cdn.jsdelivr.net/npm/comlink/dist/umd/comlink.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery.terminal/js/jquery.terminal.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/jquery.terminal/css/jquery.terminal.css" rel="stylesheet"/>

NOTE: If your function is just async and doesn't block the main thread you can just use Promises and don't need Web Worker for that.

function arbitrary_function() {
    return new Promise(resolve => {
        setTimeout(resolve, 1000);
    });
}

Instead of setTimeout, you can use any function. The rest of the code will be the same (but without a Web Worker).

about 4 years ago · Juan Pablo Isaza Denunciar

0

The problem here is how do you know the progress of your arbitary_function? It would have to update the "main process" with it's status. You can run arbitrary_function async by using setTimeout

In the example below the arbitary_function executes itself in a loop via setTimeout with random delays and updates progress variable with each execution. Meanwhile showProgress function runs in a loop independently from arbitrary_function and displays data from progress variable.

const elProgress = document.querySelector(".progress-bar > .progress");

let iProgress = 0; //this will hold the progress of our function
function arbitary_function()
{
  iProgress += Math.random() * 10;
  if (iProgress < 100)
    return setTimeout(arbitary_function, Math.random() * 500);

  iProgress = 100;
}

arbitary_function();


function showProgress(timestamp)
{
  elProgress.textContent = ~~iProgress + "%";
  elProgress.style.width = iProgress + "%";
  if (iProgress < 100)
    requestAnimationFrame(showProgress);
}

showProgress();
.progress-bar
{
  border: 1px solid black;
  height: 3em;
  border-radius: 3em;
  overflow: hidden;
}
.progress-bar > .progress
{
  background-color: red;
  height: 100%;
  border-right: 1px solid gray;
  transition: width 0.5s;
  line-height: 3em;
  text-align: center;
  vertical-align: middle;
  overflow: hidden;
}
<div class="progress-bar">
  <div class="progress"></div>
</div>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda