skip to Main Content

I’d like to await a function, call it

runThirdPartyCall()

however, I don’t know how long this will take ahead of time. If it takes longer than 30 seconds, i’d like to return from the request early, but still be able to reason about what runThirdPartyCall() returns.

Is this possible to do with workers? I see that javascript cannot directly hand over the execution of a function or the promise it returns to another thread or process once it has started, so i’m wondering if there are any alternatives.

I’m stuck wondering about the general problem, when you have a third party call of which you don’t know how long it will take, and if it ends up taking too long you want to go and inform the client/move on to other things

2

Answers


  1. Use the message facility to communicate the answer back to your mainline from the worker: –

    self.addEventListener('message', function(e) 
    {
      var data = e.data;
      switch (data.cmd) {
        case 'init':
          initThread(data.load);
          break;
        case 'stop':
          self.postMessage({'success' : true});
          self.close(); 
          break;
        default:
          self.postMessage({'success' : false, 'msg' : data.msg});
      };
    }, false);
    

    Mainline

        facFinder = new Worker("facfinder.js");
        facFinder.addEventListener('message', workerInit, false);
        
        facFinder.postMessage({'cmd' : 'init', 'load' : xmlhttp.responseText});
    
    Login or Signup to reply.
  2. I think your requirements need to be clearer, but anyway: –

    This code does NOT start on the UI thread and then miraculously switch to a WORKER thread but I believe it could match your requirements.

    Mainline: –

    <!DOCTYPE html>
    <html>
    <head>
    <script>
    document.addEventListener("DOMContentLoaded", () => {
        let wait, worker, timer, taskDone;
        
        document.getElementById("startIt").addEventListener("click", async (e) => {
            const TooLong = 5000;
            e.target.disabled = true;
            document.getElementById("stopIt").disabled = false;
            worker = new Worker("demo_worker.js");
            worker.addEventListener("message", (e) => {
                document.getElementById("result").innerHTML = e.data;
            });
            timer = setTimeout(() => {
                taskDone(-1);
                }, TooLong);
            let result = new Promise((taskResolver) => {
                taskDone = taskResolver;
                });
            let myStatus = await result;
            if (myStatus == -1)
                console.warn("It's taking too long");
        });
        
        document.getElementById("stopIt").addEventListener("click", (e) => {
            clearTimeout(timer);
            e.target.disabled = true;
            document.getElementById("startIt").disabled = false;
            if (worker != undefined)
            {
                worker.terminate();
                taskDone(1);
            }
            worker = undefined;
        });
    });
    
    </script>
    </head>
    <body>
    
    <p>Count numbers: <output id="result"></output></p>
    <button id="startIt">Start Worker</button>
    <button id="stopIt" disabled>Stop Worker</button>
    
    </body>
    </html>
    

    demo_worker.js

    var i = 0;
    
    function timedCount() {
      postMessage(++i);
      setTimeout("timedCount()",500);
    }
    
    timedCount();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search