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.
async function foo() { const p1 = new Promise((resolve) => setTimeout(() => resolve("1"), 1000)); const p2 = new Promise((_, reject) => setTimeout(() => reject("2"), 500)); const results = [await p1, await p2]; // Do not do this! Use Promise.all or Promise.allSettled instead. }
The asynchronous code will be written in three ways: callbacks, promises, and with the async / await keywords. Note: As of this writing, asynchronous programming is no longer done using only callbacks, but learning this obsolete method can provide great context as to why the JavaScript community now uses promises.
Node. js favors asynchronous APIs because it is single-threaded. This allows it to efficiently manage its own resources, but requires that long-running operations be non-blocking, and asynchronous APIs are a way to allow for control of flow with lots of non-blocking operations.
Inside an async function, you can use the await keyword before a call to a function that returns a promise. This makes the code wait at that point until the promise is settled, at which point the fulfilled value of the promise is treated as a return value, or the rejected value is thrown.
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.
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.
You should watch this: Node Tuts episode 19 - Asynchronous Iteration Patterns
It should answers your questions.
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.
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);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With