skip to Main Content

I have some questions about async and promise. (sorry guys I’m newbie at programming)

  1. Can javascript only run functions asynchronously with functions/webAPIs like XMLHttpRequest, DOM, setTimeout, etc?

  2. can we make our own function that runs asynchronously?

  3. If we make a promise function, does it run asynchronously?

// Example, does the code run asynchronously? 
function showText() {
  return new Promise((resolve) => {
    resolve("FROM PROMISE");
  });
}

console.log("HELLO");
showText().then((res) => console.log(res));
console.log("WORLD");

// Output
// HELLO
// WORLD
// FROM PROMISE

// I thought the code run async because the "WOLRD" appears before "FROM PROMISE"
  1. The question at the bottom of block code
function count() { // imagine this function is heavy and take a time to run it
  return new Promise((resolve, reject) => {
    let num = 0;
    for (let i = 1; i <= 10000000000; i++) {
      num += 1;
    }
    resolve(num);
  });
}

console.log("HELLO");
count().then((res) => console.log(res));
console.log("WORLD");

// Output
// HELLO
// WOLRD
// 10000000000

but why "WORLD" doesn't immediately appear? The "WORLD" appears simultaneously with count function

Thank you in advance

3

Answers


  1. Can javascript only run functions asynchronously with functions/webAPIs like XMLHttpRequest, DOM, setTimeout, etc

    Yes, kinda. One thing to keep in mind is that the most important difference between asynchronous and regular operations is that you give them some callback, and that callback gets ‘called back’ later with the result. DOM doesn’t belong in your list I think, most DOM operations are not asynchronous, except when you use something like addEventListener.

    can we make our own function that runs asynchronously?

    It’s an interesting question, because .. yes you can, but usually it does imply that that function used some other asynchronous operation.

    For example, if you write a function that does a HTTP request (using fetch or XMLHttpRequest) it pretty much implies that that function also must be asynchronous.

    There’s some nuance here but generally any function that calls something that’s asynchronous must itself also be asynchronous. They’re infectious that way.

    If we make a promise function, does it run asynchronously?

    I assume that with ‘promise function’ you mean: "a function that returns a promise.

    The answer is the same here, there’s no reason to use a promise unless you do something that’s already asynchronous. a Promise itself is not ‘an asynchronous operation’, but it’s an object that gives you access to the result of an asynchronous operation. A container for callbacks if you will..

    You can’t really just turn any Javascript function into an asynchronous call. Only 1 line of Javascript can run at the same time. They’re not threads. Asynchronous operations are generally ‘functions you call that live outside the Javascript engine that you get a result for slightly later’.

    If you’re looking for a way explicitly for something like that’s like a Thread in other languages, you might need to look into Webworkers.

    Login or Signup to reply.
  2. The whole question and answer revolve around the event loop in javascript. The way your code is executed includes the ‘stack’, the ‘message queue’ and the ‘micro tasks queue’. The events that happen usually go to the ‘message queue’, but promises actually go to the ‘microtasks queue’. The difference is ‘First, each time a task exits, the event loop checks to see if the task is returning control to other JavaScript code. If not, it runs all of the microtasks in the microtask queue’ and ‘Second, if a microtask adds more microtasks to the queue by calling queueMicrotask(), those newly-added microtasks execute before the next task is run.’
    TLDR: You can creqte your async functions (creating a Promise is one example) and there are certain differences in how they get executed by the engine compared to procedural and synchronous code

    Source: https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide

    Login or Signup to reply.
  3. Asynchronous does not mean "parallel" it just mean "can happen at any time".

    The following code is fully synchronous, with zero async functionality yet it implements an asynchronous timeout function:

    const now = () => Date.now();
    
    // timer event "queue"
    let timers = [];
    
    const set_timeout = (callback, delay) => {
        const startTime = now();
    
        // push microtask into queue:   
        timers.push(() => {
            if (now() - startTime >= delay) {
                callback();
                return true;
            }
            return false;
        });
    }
    
    const timer_event_loop = () => {
        while (1) {
            if (timers.length == 0) break;
            
            for (let i=0; i<timers.length; i++) {
                if (timers[i]()) {
                    timers.splice(i,1); // delete microtask from timer "queue"
                }
            }
        }
    }
    

    Now we can use the asynchronous set_timeout function implemented in fully synchronous code (note: this design pattern is very useful if you’re doing microcontroller development, for example in Arduino programming):

    console.log('hello');
    
    set_timeout(() => console.log('goodbye'),500);
    
    console.log('world');
    
    timer_event_loop(); // this runs forever until there's no more events
    

    If you run the code you will notice that our synchronously implemented set_timeout function behaves similarly to setTimeout. This is because it is asynchronous: it does not run in parallel but its callback does not run immediately – it runs at some future time. This is the definition of asynchronous.

    We can even use Promises with this set_timeout function:

    const promisified_timeout = (delay) => {
        return new Promise((resolve,reject) => {
            set_timeout(resolve, delay);
        });
    }
    

    Now we can run this:

    console.log('hello');
    
    promisified_timeout(500).then(() => console.log('goodbye'));
    
    console.log('world');
    
    timer_event_loop(); // this runs forever until there's no more events
    

    It still behaves like regular asynchronous code even if we haven’t used any asynchronous feature of the OS.

    The difference between this synchronous demo and what javascript does is that javascript hides the event loop from us so we don’t have to manually call the event loop at the end of our code (like we must in a lot of C++/C#/Java frameworks) and also it implements setTimeout using OS provided timers which works with interrupts so it doesn’t waste CPU time.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search