how to create a custom asynchronous function in node.js

10,076

Solution 1

There are multiple ways to achieve this in JavaScript (not node-specific, but there are modules that make your life easier):


callbacks

They are somewhat continuations and it is a shame developers were bothered with handling them manually (compilers used to do that themselves). But they work:

function callee(callback) {
  setTimeout(function() {
    callback(null, 'finished!');
  }, 2000);
}

function caller() {
  document.write('started!');
  callee(function(err, result) {
    document.write(result);
  });
}

caller();

It is common in the node environment to indicate errors with the first parameter of the callback (like callback(new Error("something wrong!"))).


promises

As callbacks get ugly when nested (imagine 10-20 of them, you'd be screwed debugging this), the idea of promises came up. You might know them as Futures from java. They are built-in to ES6, and you can use them beforehand in the node environment with npm i promise -- many client-side frameworks (e.g. jQuery, AngularJS) have their own implementations. Originally there was Q.

var Promise = require('promise');

function callee() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('finished!');
    }, 1000);
  });
}

function caller() {
  document.write('started!');
  callee().then(function(result) {
    document.write(result);
  });
}

caller();

generators

ES6 has generators. You might know them from python.

They provide asynchronity as well, as they yield new values once they are computed.

I recommend reading Learn ES2015 for more information on that.

My personal opinion is to never ever use generators as they interfere heavily with promises and make debugging really hard.


async/await

ES7 will make life a whole lot easier with async/await. You can basically say that a function will be performed asynchronously and that you want to await a result (once you are in a async function). ES7 async functions is a good start to read on that. It's like

async function callee() {
  return (() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve('finished!'), 1000);
    })
  })();
}

async function caller() {
  document.write('started!');
  document.write(await callee());
}

// the global async wrapper
(async function() {
  caller();
})();

Solution 2

I have tried to provide a better version of @Dominik Schreiber's answer

async function callee() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve('finished!'), 1000);
  })
}

async function caller() {
  console.log('started!');
  console.log(await callee());
}

caller();

Solution 3

You can add a callback to the event que with

 process.nextTick(callback);

Don't do that, it is almost never what you want. JavaScript is single threaded so adding a callback still blocks the call of f2. If you have a function that takes a long time to run run it in a child_process or even better, create a separate micro service for it.

Share:
10,076
Ankit
Author by

Ankit

Updated on June 28, 2022

Comments

  • Ankit
    Ankit almost 2 years

    Ii'm trying to do something like.

    function fun1(){
      for(var j=0;j<20;j++)
      {
        var n = j;
        console.log("i= "+n);
      }
    }
    function fun2()
    {
      console.log("In Callback");
    }  
    
    fun1();
    fun2();

    its working fine till now and got output as expected.

    But, I want to call function fun1() and fun2() asynchronously it means fun2() call before fun1(), b'coz fun1() will take some time for complete the execution as compare to fun2().

    How can I achieve this, Node.js provide asynchronous function, Is it already defined function can asynchronous only or we can make them according our need.