Reputation: 8705
I've tried to research on how exactly asynchronous functions should be written. After a lot of plowing through a lot of documentation, it's still unclear to me.
How do I write asynchronous functions for Node? How should I implement error event handling correctly?
Another way to ask my question would be this: How should I interpret the following function?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
Also, I found this question on SO ("How do I create a non-blocking asynchronous function in node.js?") interesting. I don't feel like it has been answered yet.
Upvotes: 114
Views: 110436
Reputation: 917
I've dealing too many hours for such task in for node.js. I'm mainly front-end guy.
I find this quite important, because all node methods asyncronous deal with callback, and transform it into Promise is better to handle it.
I Just want to show a possible outcome, more lean and readable. Using ECMA-6 with async you can write it like this.
async function getNameFiles (dirname) {
return new Promise((resolve, reject) => {
fs.readdir(dirname, (err, filenames) => {
err !== (undefined || null) ? reject(err) : resolve(filenames)
})
})
}
the (undefined || null)
is for repl (read event print loop) scenarios,
using undefined also work.
Upvotes: 0
Reputation: 2038
If you KNOW that a function returns a promise, i suggest using the new async/await features in JavaScript. It makes the syntax look synchronous but work asynchronously. When you add the async
keyword to a function, it allows you to await
promises in that scope:
async function ace() {
var r = await new Promise((resolve, reject) => {
resolve(true)
});
console.log(r); // true
}
if a function does not return a promise, i recommend wrapping it in a new promise that you define, then resolve the data that you want:
function ajax_call(url, method) {
return new Promise((resolve, reject) => {
fetch(url, { method })
.then(resp => resp.json())
.then(json => { resolve(json); })
});
}
async function your_function() {
var json = await ajax_call('www.api-example.com/some_data', 'GET');
console.log(json); // { status: 200, data: ... }
}
Bottom line: leverage the power of Promises.
Upvotes: 3
Reputation: 1993
Just passing by callbacks is not enough. You have to use settimer for example, to make function async.
Examples: Not async functions:
function a() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
};
function b() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
};
function c() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
};
a();
console.log("This should be good");
If you will run above example, This should be good, will have to wait untill those functions will finish to work.
Pseudo multithread (async) functions:
function a() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
b();
}, 0);
};
function b() {
setTimeout ( function() {
var a = 0;
for(i=0; i<10000000; i++) {
a++;
};
c();
}, 0);
};
function c() {
setTimeout ( function() {
for(i=0; i<10000000; i++) {
};
console.log("async finished!");
}, 0);
};
a();
console.log("This should be good");
This one will be trully async. This should be good will be writen before async finished.
Upvotes: 9
Reputation: 5007
You should watch this: Node Tuts episode 19 - Asynchronous Iteration Patterns
It should answers your questions.
Upvotes: 5
Reputation: 117
Try this, it works for both node and the browser.
isNode = (typeof exports !== 'undefined') &&
(typeof module !== 'undefined') &&
(typeof module.exports !== 'undefined') &&
(typeof navigator === 'undefined' || typeof navigator.appName === 'undefined') ? true : false,
asyncIt = (isNode ? function (func) {
process.nextTick(function () {
func();
});
} : function (func) {
setTimeout(func, 5);
});
Upvotes: 2
Reputation: 169373
You seem to be confusing asynchronous IO with asynchronous functions. node.js uses asynchronous non-blocking IO because non blocking IO is better. The best way to understand it is to go watch some videos by ryan dahl.
How do I write asynchronous functions for Node?
Just write normal functions, the only difference is that they are not executed immediately but passed around as callbacks.
How should I implement error event handling correctly
Generally API's give you a callback with an err as the first argument. For example
database.query('something', function(err, result) {
if (err) handle(err);
doSomething(result);
});
Is a common pattern.
Another common pattern is on('error')
. For example
process.on('uncaughtException', function (err) {
console.log('Caught exception: ' + err);
});
Edit:
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
The above function when called as
async_function(42, function(val) {
console.log(val)
});
console.log(43);
Will print 42
to the console asynchronously. In particular process.nextTick
fires after the current eventloop callstack is empty. That call stack is empty after async_function
and console.log(43)
have run. So we print 43 followed by 42.
You should probably do some reading on the event loop.
Upvotes: 86