Run Function Asynchronously

JavaScriptJavaScriptBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we will learn how to execute long-running functions asynchronously by using a Web Worker. The purpose of the lab is to teach developers how to run functions in a separate thread, allowing them to avoid blocking the UI while the function is executing. The lab provides a practical example of how to create a Web Worker and use it to run a function.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("`JavaScript`")) -.-> javascript/BasicConceptsGroup(["`Basic Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/AdvancedConceptsGroup(["`Advanced Concepts`"]) javascript(("`JavaScript`")) -.-> javascript/ToolsandEnvironmentGroup(["`Tools and Environment`"]) javascript/BasicConceptsGroup -.-> javascript/variables("`Variables`") javascript/BasicConceptsGroup -.-> javascript/data_types("`Data Types`") javascript/BasicConceptsGroup -.-> javascript/arith_ops("`Arithmetic Operators`") javascript/BasicConceptsGroup -.-> javascript/comp_ops("`Comparison Operators`") javascript/BasicConceptsGroup -.-> javascript/loops("`Loops`") javascript/BasicConceptsGroup -.-> javascript/obj_manip("`Object Manipulation`") javascript/AdvancedConceptsGroup -.-> javascript/async_prog("`Asynchronous Programming`") javascript/AdvancedConceptsGroup -.-> javascript/template_lit("`Template Literals`") javascript/ToolsandEnvironmentGroup -.-> javascript/debugging("`Debugging`") subgraph Lab Skills javascript/variables -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/data_types -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/arith_ops -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/comp_ops -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/loops -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/obj_manip -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/async_prog -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/template_lit -.-> lab-28606{{"`Run Function Asynchronously`"}} javascript/debugging -.-> lab-28606{{"`Run Function Asynchronously`"}} end

Asynchronous Function Execution Using Web Workers

To execute a function without blocking the UI, use a Web Worker to run the function in a separate thread. Here's how:

  1. Create a Worker using a Blob object URL, with the contents being the stringified version of the function to be executed.
  2. Immediately post the return value of calling the function back.
  3. Return a Promise, listening for onmessage and onerror events and resolving the data posted back from the worker, or throwing an error.
const runAsync = (fn) => {
  const worker = new Worker(
    URL.createObjectURL(new Blob([`postMessage((${fn})());`]), {
      type: "application/javascript; charset=utf-8"
    })
  );
  return new Promise((resolve, reject) => {
    worker.onmessage = ({ data }) => {
      resolve(data);
      worker.terminate();
    };
    worker.onerror = (error) => {
      reject(error);
      worker.terminate();
    };
  });
};

Note that the function supplied to runAsync should not use closures because everything gets stringified and becomes literal. Therefore, all variables and functions must be defined inside. Here are some examples:

const longRunningFunction = () => {
  let result = 0;
  for (let i = 0; i < 1000; i++)
    for (let j = 0; j < 700; j++)
      for (let k = 0; k < 300; k++) result = result + i + j + k;

  return result;
};

runAsync(longRunningFunction).then(console.log); // 209685000000
runAsync(() => 10 ** 3).then(console.log); // 1000
let outsideVariable = 50;
runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'

Summary

Congratulations! You have completed the Run Function Asynchronously lab. You can practice more labs in LabEx to improve your skills.

Other JavaScript Tutorials you may like