Node js wrap async function - javascript

I'm implementing an API which has a function:
get(url)
Which returns a Response Object, i.e. no callback. The Http Modules I have found implements node-style async functions with callbacks. I have tried to wait for the async function to return in several ways, using Fibers etc. Fibers solves the issue within the Fiber, but can't be used in my case as I need to return the value outside any Fiber.
It might be possible to wrap the Entire Execution (including the code using the API) but I really don't want this. Is there any module that does what I want?

If I understand the question, that you're trying to mix asynchronous code with synchronous code what you're trying to accomplish is not really possible without promises. As soon as you mix asynchronous code with synchronous code, you make the entire code asynchronous, or you risk the synchronous code returning a value before the result from the synchronous code is returned.
You could always try a timeout on the function that holds it returning until a given time period has expired, which hopes that the asynchronous code executes and has a return value before the synchronous code returns. However, this is extremely inefficient, and does not eliminate the problem as you could still end up returning before the asynchronous portion has finished.
I'd also agree with the comment from robertklep that node.js really does not fit your use case, and you might be better looking at another tool for the job.

Related

Using a fetch promise synchronously

I need a synchronous function (it can be blocking).
I need to use Fetch, and when the promise is ready, I want to return it on the synchronous function.
Everywhere I look I can't find the answer.
I need a synchronous function
Unlikely.
(it can be blocking).
That is what synchronous means.
Long running blocking functions (including network operations) cause serious usability problems and should be avoided.
I need to use Fetch, and when the promise is ready, I want to return it on the synchronous function.
That is not possible.
XMLHttpRequest has a synchronous mode, although it is deprecated and should not be used.
You can activate it by passing false as the third parameter to open.
xhr.open("METHOD as string", "URL as strong", false);
fetch learned lessons from XMLHttpRequest and did not implement anything similar.
Learn how to deal with asynchronous code instead. The async and await keywords will let you write in in a synchronous style.
You can't block the main thread like this, the browser won't allow you(or nodejs, since I don't know which). There's no synchronous way to fetch like that. You can instead use async/await to have your code avoid callbacks. It's probably highly unadvised to do what you want to and there's a better solution, but I can't tell you much more because of lacking context.

Is there any reason to prefer the async versions of functions in node.js while calling them from inside an async function?

Mainly looking at the FS api, for most functions it seems there are three flavors to choose from:
Synchronous
Asynchronous using callback
Asynchronous using promises
Async is the superior way to use system resources, however, if I'm already inside an async function and am awaiting every call anyway then there shouldn't be any difference between that and just using synchronous calls, right? To me it just seems like a built in await statement.
I don't know how async is implemented in js/node though. Is there any advantage to using async functions if I'm inside an async function to begin with? (excluding scenarios when I'm running async tasks in parallel)
One should decide to use an async function ONLY based on what is going on inside that function, not on who is calling it. The caller does not affect whether a function should be async or not.
Reasons to make a function async:
You have promise-based asynchronous operations inside the function and you wish to use await.
You have promise-based asynchronous operations inside the function and you wish to take advantage of the automatic catching of synchronous exceptions (and conversion to a rejected promise) that might occur before you invoke your asynchronous operations.
And, that's pretty much it for the reasons to use the async keyword in front of a function.
Things that an async function is NOT (or common misconceptions about async functions):
It doesn't magically make blocking code become non-blocking.
It doesn't make the caller run faster.
It doesn't make synchronous code now run in the background asynchronously.
Async is the superior way to use system resources,
Not sure what you mean there. Asynchronous functions allow you to run operations in a non-blocking fashion so that the main thread in Javascript can do other things while the asynchronous operation is running, but that is not something that an async function enables. That's enabled by an asynchronous operation. The two are different.
if I'm already inside an async function and am awaiting every call anyway then there shouldn't be any difference between that and just using synchronous calls, right?
Incorrect. Using await with a function that returns a promise does suspend execution of the current function (returning a promise immediately), but that allows the main Javascript thread to do other things, serve other requests, etc... Using synchronous code would be blocking and would not allow the main thread to do other things, thus ruining the scalability of a server.
To me it just seems like a built in await statement.
Blocking, synchronous code affects everything else that could be running during your operation. It's not the same as using await.
async/await is not equivalent to synchronous execution; it's syntactic sugar to make working with promises easier (indeed, the goal of these keywords is to make promises closer to writing synchronous code from a programming standpoint and therefore more intuitive to use).
async places a task on the event loop which will execute after all synchronous execution pending on the stack finishes. The advantages of this are clear: the process can do work while waiting for resources to be available (opening a file involves a system call, for example, so it makes sense to make this a non-blocking operation).
If you're already inside an asynchronous function, the advantages and drawbacks of asynchronous operations are just the same as they would be anywhere else. In fact, await can only be used in an async function.

Abstracting away asynchronicity/promises in javascript?

Suppose I have written a library class:
class ComplexThingDoer implements ThingDoer {
...
doComplexThing(arg1, arg2) {
// lots of complex code here
return finalResult;
}
...
}
And I have made this class available to others, who are using it as intended, completely ignorant of how doComplexThing actually does the complex thing and making use of the finalResult for whatever they're using it for.
Now, suppose I decide that I actually want to reimplement doComplexThing so that instead of synchronously running a lot of complex code here, it makes a request to a specialized server that returns the final result. Or makes a call to a database in which results of the complex thing have been precalculated. Or does one of those things the first time it's called with a particular set of arguments, and caches the result so that the next time it's called with the same arguments it can just return the previously-calculated value.
As far as I can tell, whether I use callbacks, Promises, or async/await, I am screwed - I can't do any of those things without breaking my interface. I have to return a Promise, or accept a callback, or something - there doesn't seem to be any way to just not return until I have the result, the way I've always done before. My callers don't care how I'm getting the result; they just want the result.
Am I missing something? Is there in fact a way to "de-promisify" a function so that its caller doesn't have to know that it's performing an asynchronous operation? Should I be pre-emptively writing everything as Promises just in case someday I might want to reimplement it in an asynchronous way (sounds like a terrible idea)?
Thanks!
Nope, you're not missing anything. If you make your function asynchronous, then every caller of it will have to treat it as such and also be asynchronous itself. The result of an asynchronous call will be available sometime later, on subsequent iterations of the underlying event loop. There is absolutely no way to block synchronous code to wait for that, because if you block in code the event loop won't advance and the result will never become available.
Switching an interface from synchronous to asynchronous is a breaking change.

Node js - How to a job in sequential order

Iam a node js beginner. I want to do some Job in Node js in a sequential order.
Fetch from DB -> Do some operation -> export as excel -> Mail
As Node js async,Do I need to code like below?
function fetchDB();
function operation(results,callback);
function excel(result,callback());
function mail(result);
fetchDB(operation(results,excel(result,mail(result))));
is the above way is right? or any other good ways to achieve this?
I suggest you read into promises. They allow you to run code immediately after asynchronous code returns. Also see promisejs.org as noted in the comments by #AnnaFohlmeister.
Promises are a more advanced (and cleaner) implementation of callbacks and can allow for more complex chaining of actions after asynchronous code finishes. Using callbacks you tend to run into what is called "callback hell" where you will have a ton of different actions nested into many callbacks and is not easy to write in a modular way (like changing out which operations do what after the end of which call).
As for your code it's correct using callbacks, though when defining excel(result, callback()) remove () on the callback because that will most likely confuse node when it's initializing the functions. Also I'm assuming that your excel function makes another asynchronous call in it.

In Javascript, generally, how to make asynchronous function synchronous?

Let's say there is a function like this in a third-party javascript (not NodeJS) module:
Api.IoAsync(parameter, function(err, message) {
...
})
And I want to convert it into a synchronous version like this:
Api.IoSync(parameter)
It will be blocking until complete, and its return value is message if succeed, else err.
Is there an universal and easy way to do this?
You cannot make an asynchronous function behave synchronously in Javascript. This has been asked many times. It cannot be done in Javascript.
If the underlying function is asynchronous, then you will have to code an asynchronous response callback and use the results of the async function that way. There is no work-around.
Learn how to code with async callbacks and move forward. Promises can simplify the use of asynchronous functions by allowing you to sequence and chain async operations more easily, but they still use callbacks to process results.

Categories