[javascript] How can I create an Asynchronous function in Javascript?

Check out this code :

<a href="#" id="link">Link</a>
<span>Moving</span>

$('#link').click(function () {
    console.log("Enter");
    $('#link').animate({ width: 200 }, 2000, function() {
         console.log("finished");            
    });    
    console.log("Exit");    
});

As you can see in the console, the "animate" function is asynchronous, and it "fork"s the flow of the event handler block code. In fact :

$('#link').click(function () {
    console.log("Enter");
    asyncFunct();
    console.log("Exit");    
});

function asyncFunct() {
    console.log("finished");
}

follow the flow of the block code!

If I wish to create my function asyncFunct() { } with this behaviour, how can I do it with javascript/jquery? I think there is a strategy without the use of setTimeout() ?

This question is related to javascript jquery function asynchronous

The answer is


If you want to use Parameters and regulate the maximum number of async functions you can use a simple async worker I've build:

var BackgroundWorker = function(maxTasks) {
    this.maxTasks = maxTasks || 100;
    this.runningTasks = 0;
    this.taskQueue = [];
};

/* runs an async task */
BackgroundWorker.prototype.runTask = function(task, delay, params) {
    var self = this;
    if(self.runningTasks >= self.maxTasks) {
        self.taskQueue.push({ task: task, delay: delay, params: params});
    } else {
        self.runningTasks += 1;
        var runnable = function(params) {
            try {
                task(params);
            } catch(err) {
                console.log(err);
            }
            self.taskCompleted();
        }
        // this approach uses current standards:
        setTimeout(runnable, delay, params);
    }
}

BackgroundWorker.prototype.taskCompleted = function() {
    this.runningTasks -= 1;

    // are any tasks waiting in queue?
    if(this.taskQueue.length > 0) {
        // it seems so! let's run it x)
        var taskInfo = this.taskQueue.splice(0, 1)[0];
        this.runTask(taskInfo.task, taskInfo.delay, taskInfo.params);
    }
}

You can use it like this:

var myFunction = function() {
 ...
}
var myFunctionB = function() {
 ...
}
var myParams = { name: "John" };

var bgworker = new BackgroundWorker();
bgworker.runTask(myFunction, 0, myParams);
bgworker.runTask(myFunctionB, 0, null);

MDN has a good example on the use of setTimeout preserving "this".

Like the following:

function doSomething() {
    // use 'this' to handle the selected element here
}

$(".someSelector").each(function() {
    setTimeout(doSomething.bind(this), 0);
});

Edit: I totally misunderstood the question. In the browser, I would use setTimeout. If it was important that it ran in another thread, I would use Web Workers.


Here is a function that takes in another function and outputs a version that runs async.

var async = function (func) {
  return function () {
    var args = arguments;
    setTimeout(function () {
      func.apply(this, args);
    }, 0);
  };
};

It is used as a simple way to make an async function:

var anyncFunction = async(function (callback) {
    doSomething();
    callback();
});

This is different from @fider's answer because the function itself has its own structure (no callback added on, it's already in the function) and also because it creates a new function that can be used.


Late, but to show an easy solution using promises after their introduction in ES6, it handles asynchronous calls a lot easier:

You set the asynchronous code in a new promise:

var asyncFunct = new Promise(function(resolve, reject) {
    $('#link').animate({ width: 200 }, 2000, function() {
        console.log("finished");                
        resolve();
    });             
});

Note to set resolve() when async call finishes.
Then you add the code that you want to run after async call finishes inside .then() of the promise:

asyncFunct.then((result) => {
    console.log("Exit");    
});

Here is a snippet of it:

_x000D_
_x000D_
$('#link').click(function () {_x000D_
    console.log("Enter");_x000D_
    var asyncFunct = new Promise(function(resolve, reject) {_x000D_
        $('#link').animate({ width: 200 }, 2000, function() {_x000D_
            console.log("finished");             _x000D_
            resolve();_x000D_
        });    _x000D_
    });_x000D_
    asyncFunct.then((result) => {_x000D_
        console.log("Exit");    _x000D_
    });_x000D_
});
_x000D_
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>_x000D_
<a href="#" id="link">Link</a>_x000D_
<span>Moving</span>
_x000D_
_x000D_
_x000D_

or JSFiddle


Function.prototype.applyAsync = function(params, cb){
      var function_context = this;
      setTimeout(function(){
          var val = function_context.apply(undefined, params); 
          if(cb) cb(val);
      }, 0);
}

// usage
var double = function(n){return 2*n;};
var display = function(){console.log(arguments); return undefined;};
double.applyAsync([3], display);

Although not fundamentally different than the other solutions, I think my solution does a few additional nice things:

  • it allows for parameters to the functions
  • it passes the output of the function to the callback
  • it is added to Function.prototype allowing a nicer way to call it

Also, the similarity to the built-in function Function.prototype.apply seems appropriate to me.


You can use a timer:

setTimeout( yourFn, 0 );

(where yourFn is a reference to your function)

or, with Lodash:

_.defer( yourFn );

Defers invoking the func until the current call stack has cleared. Any additional arguments are provided to func when it's invoked.


here you have simple solution (other write about it) http://www.benlesh.com/2012/05/calling-javascript-function.html

And here you have above ready solution:

function async(your_function, callback) {
    setTimeout(function() {
        your_function();
        if (callback) {callback();}
    }, 0);
}

TEST 1 (may output '1 x 2 3' or '1 2 x 3' or '1 2 3 x'):

console.log(1);
async(function() {console.log('x')}, null);
console.log(2);
console.log(3);

TEST 2 (will always output 'x 1'):

async(function() {console.log('x');}, function() {console.log(1);});

This function is executed with timeout 0 - it will simulate asynchronous task


Unfortunately, JavaScript doesn't provide an async functionality. It works only in a single one thread. But the most of the modern browsers provide Workers, that are second scripts which gets executed in background and can return a result. So, I reached a solution I think it's useful to asynchronously run a function, which creates a worker for each async call.

The code below contains the function async to call in background.

Function.prototype.async = function(callback) {
    let blob = new Blob([ "self.addEventListener('message', function(e) { self.postMessage({ result: (" + this + ").apply(null, e.data) }); }, false);" ], { type: "text/javascript" });
    let worker = new Worker(window.URL.createObjectURL(blob));
    worker.addEventListener("message", function(e) {
        this(e.data.result);
    }.bind(callback), false);
    return function() {
        this.postMessage(Array.from(arguments));
    }.bind(worker);
};

This is an example for usage:

(function(x) {
    for (let i = 0; i < 999999999; i++) {}
        return x * 2;
}).async(function(result) {
    alert(result);
})(10);

This executes a function which iterate a for with a huge number to take time as demonstration of asynchronicity, and then gets the double of the passed number. The async method provides a function which calls the wanted function in background, and in that which is provided as parameter of async callbacks the return in its unique parameter. So in the callback function I alert the result.


Next to the great answer by @pimvdb, and just in case you where wondering, async.js does not offer truly asynchronous functions either. Here is a (very) stripped down version of the library's main method:

function asyncify(func) { // signature: func(array)
    return function (array, callback) {
        var result;
        try {
            result = func.apply(this, array);
        } catch (e) {
            return callback(e);
        }
        /* code ommited in case func returns a promise */
        callback(null, result);
    };
}

So the function protects from errors and gracefully hands it to the callback to handle, but the code is as synchronous as any other JS function.


This page walks you through the basics of creating an async javascript function.

Since ES2017, asynchronous javacript functions are much easier to write. You should also read more on Promises.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to asynchronous

How to read file with async/await properly? Use Async/Await with Axios in React.js Waiting until the task finishes How to reject in async/await syntax? React - Display loading screen while DOM is rendering? angular 2 how to return data from subscribe How do I access store state in React Redux? SyntaxError: Unexpected token function - Async Await Nodejs Why does .json() return a promise? Why is setState in reactjs Async instead of Sync?