Execute Program

JavaScript Concurrency: setTimeout and Functions

Welcome to the setTimeout and Functions lesson!

This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!

  • setTimeout works in the same way when we wrap our code in functions, classes, or any other language construct.

  • (Note that the next example says "async result:", not just "result:". That indicates that Execute Program will wait for the timer to finish, so we'll see the array contents after the array.push has already run.)

  • >
    function doAsyncWork() {
    const array = [];
    setTimeout(() => array.push('it worked'), 1000);
    return array;
    }
    const array = doAsyncWork();
    array;
    Asynchronous Icon Async Result:
    ['it worked']Pass Icon
  • As our examples get more complex, we'll want to extract our asynchronous callbacks into their own functions. Here's an example of that: we asynchronously collect users' names in an array.

  • >
    const users = [
    {name: 'Amir'},
    {name: 'Betty'},
    ];

    function addUserName(names, user) {
    names.push(user.name);
    }

    function doAsyncWork() {
    const names = [];
    for (const user of users) {
    setTimeout(() => addUserName(names, user), 1000);
    }
    return names;
    }

    const array = doAsyncWork();
    array;
    Asynchronous Icon Async Result:
    ['Amir', 'Betty']Pass Icon
  • Extracting callbacks like this makes changing code easier. If we're tracking down a bug where asynchronous code seems to execute in the wrong order, we'll start by looking at doAsyncWork. But if we're fixing a bug in the work itself, we'll start by looking at addUserName.

  • (Of course, real-world equivalents of addUserName will be more than one line long. Imagine that function being 10 lines long instead of 1!)

  • Here's a code problem:

    Set a timer to call the addMessage function after 100 ms.

    (This example uses .slice() to duplicate the messages array's value before any timers run. That lets us check the value of the array before and after the timer finishes.)

    const messages = [];
    function addMessage() {
    messages.push('It worked!');
    }
    setTimeout(addMessage, 100);
    const initialMessages = messages.slice();
    [initialMessages, messages];
    Asynchronous Icon Async Result:
    Goal:
    [[], ['It worked!']]
    Yours:
    [[], ['It worked!']]Pass Icon