how to create a custom asynchronous function in node.js
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.
Ankit
Updated on June 28, 2022Comments
-
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()
andfun2()
asynchronously it meansfun2()
call beforefun1()
, b'cozfun1()
will take some time for complete the execution as compare tofun2()
.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.