What is Async in Nodejs - node.js

If I am trying to write an app.post() function why do some examples use async and some just writes a regular function(req,res)? What does async do that is different from regular function?

async (Asynchronous) function gives your code the ability to pause for any action. Let's see some examples:
SamplePost = (data) => {
let result;
result = Request.Send("POST", data);
console.log(result);
}
If you run the above function with an actual POST request It'll print null because by the time the result of the request will be fetched the console.log will finish executing.
SamplePost = async (data) => {
let result;
result = await Request.Send("POST", data);
console.log(result);
}
But in the above code it will print the actual result. Because this time the code will pause at the async and as long as it doesn't return any value (Not a Promise) it'll keep waiting and as soon as it'll get a return value it'll continue the code.
Sorry in advance for overcomplicating

Related

Wait for loop is finished to run the rest of the program

I want to push on my array all the data which are on the feed variable. I need to access to the data array variable outside of the foreach loop.
But the console.log is execute before the loop.
I have try to change the promise to an async await and it is the same.
let data = []
sources.forEach((src) => {
parser.parseURL(src.rss, (err, feed) => {
data.push(feed)
})
})
console.log(data)
Thank you to you help.
I could make an ad-hoc debounce function.. debounce as in it'll run n milliseconds AFTER it's finished calling.. surprisingly, 0 milliseconds would still occur after an instruction written below it.. using that logic, here's an example
var debObj={}; //empty object SOLELY for temporary storage of the debounce function
function debounce(fn,n,obj){ //debounce function
function doIt(){
obj[fn.toString()]=[fn,setTimeout(()=>{
fn();delete(obj[fn.toString()])
},n)]
}
if(obj[fn.toString()]){
clearTimeout(obj[fn.toString()][1])
doIt(); return;
}
doIt(); return;
}
function debouncer(fn,n){return function(){debounce(fn,n,debObj)}} //debounce function that imitates the functionality of the real debounce
//now for your code snippet...............................................................
let data = []
let logIt=debouncer(()=>console.log(data),0)
sources.forEach((src) => {
parser.parseURL(src.rss, (err, feed) => {
data.push(feed)
})
logIt()
})
I know it's extremely adhoc.. but does it work?

Can't change the var value outside function

I need to change the value of result var, but I'm not getting.
My code:
var request = require('request');
var result = ""
function getQuote(callback){
return new Promise((resolve,reject) => {
request({'method': 'GET','url': 'https://blockchain.info/ticker'}, function (error, response) {
if (error) return reject(error);
return resolve(callback(response.body))
})
})
}
getQuote((data) => { result = data })
console.log(result) // return is empty
Thanks!
getQuote is an asynchronous function. When you call console.log(result), it may not call the callback function (data) => { result = data } you passed in while getQuote is still waiting for the response of your request. So, result is still the initialized value which is empty string.
try to log the result after the promise is fulfilled, such as getQuote((data) => { result = data }).then(()=>console.log(result))
Javascript engine will not wait for the promise to finish executing. Immediately after calling getQuote(), it will proceed executing the next line, i.e, console.log(result), which is simply empty and not yet assigned any value, because it will take some time to finish completing Promise-Get method.
You need to research and understand Javascript Execution Context and Event Looping.
https://blog.bitsrc.io/understanding-asynchronous-javascript-the-event-loop-74cd408419ff

Async Await Behaviour

A simple code to understand async/await is making me crazy.
I have a button on click on which i am reading some value from localstorage and showing it in an alert box. Before showing the alert i want to console.log the value.
If i understood async/await my code should d exactly that but it is working in reverse order. first the alert is coming and then the console.
//Method called on button click
findMyAge2() {
this.getData("age").then(result => {
console.log('Hi');
myAge2 = result;
});
alert(myAge2);
}
async getData(key): Promise<any> {
return await this.storage.get(`${key}`);
}
Expected Result:
in Console log :Hi
UI: Age
Actual Results:
UI: Age
in Console log :Hi
JavaScript is asynchronous by nature, so when you have a Promise returned, code continues execution and that Promise resolves some time afterward.
async/await is a way to control this flow of programming and can allow you to create Synchronous code that "awaits" the result of asynchronous execution.
Your problem here is that you want to return the promise from your getData function and await it in your findMyAge2 function.
async function findMyAge2() {
let result = await this.getData("age");
console.log('Hi');
myAge2 = result;
alert(myAge2);
}
async getData(key): Promise<any> {
return this.storage.get(`${key}`);
}
By adding async keyword to a function it will always now return a Promise. So you do not need to await in your return statement. That effectively does nothing. It would be like saying:
function getData(key) {
return new Promise(resolve => {
return localStorage.get(`${key}`).then(result => resolve(result))
})
}
You don't need to await that result in local storage because the consumer should be calling await or .then on the result regardless.
Try this way,
findMyAge2() {
this.getData("age").then(result => {
console.log('Hi');
myAge2 = result;
alert(myAge2);
});
}
async getData(key): Promise<any> {
return await this.storage.get(`${key}`);
}
Before you should wait to alert before data being retrieved.
async/await works like with promises, which means, code gets executed and you don't know when it will finish, you just know that after if finishes, you want something else to be executed.
This is exactly what you put inside the "then" function, which is what gets executed after the 1st part (asyc getData) gets executed.
In the case of your code, the findMyAge2 gets called when you click the button, then it executes the getData and specifies what happens after getting the result from that call, within the "then" block.
Therefore you just have to move the alert, into "then" block, then you'll have the result you expect.
var myAge2;
findMyAge2() {
this.getData("age").then(result => {
console.log('Hi');
myAge2 = result;
alert(myAge2);
});
}
async getData(key): Promise<any> {
return await this.storage.get(`${key}`);
}

Why does await function return pending promise

let request = require('request-promise')
function get(url) {
let _opt = {}
let response = (async () => {
try {
var ret = await request(url, _opt);
return ret;
} catch (e) {
console.log(e)
}
})();
return response
}
console.log(get('http://www.httpbin.org/ip'))
gives:
Promise { <pending> }
Why doesn't it wait for my response?
Why doesn't it wait for my response?
That's simple, because you are returning a promise. Node js is single thread and is executed in a non blocking way.
That means that return response in your get function is executed before the resolution of response variable.
Try as follow:
let request = require('request-promise')
function get(url) {
let _opt = {}
return request(url, _opt);
}
async function some () {
console.log(await get('http://www.httpbin.org/ip'));
}
some();
This example is also returning a promise, but in this case we are awaiting for the promise resolution.
Hope this help.
Async functions are non-blocking and will immediately return a promise rather than waiting for a result. This for example, allows for multiple async functions to run concurrently rather than each running sequentially.
To wait for a result, you can use the await keyword to block until the promise is resolved. The await command will return the result of the promise. For example, to log the result of the get function, you can change the last line to:
console.log(await get('http://www.httpbin.org/ip'))
UPDATE:
Let me give this one more try (sorry if I'm beating a dead horse here).
Since your response variable is an async function, it's return type is a promise by the definition of an async function. Even though the ret variable is await'ed, that just means that it will block while writing to the ret variable. The response async function needs to be run to completion in order for the await to complete. An await here would be useful if you wanted to wait for the return value and then add post-processing, but in this example specifically, your try block could simply be:
try {
return request(url, _opt)
}
Since request already returns a promise, the extra await is causing a trivial amount of overhead since it implicitly creates an extra promise.
Since response is a promise, and you are returning response, the function get is also returning a promise. You are then trying to log this promise (which obviously doesn't work). This is why you must await or .then the get function to get the result.
Source: https://medium.com/#bluepnume/learn-about-promises-before-you-start-using-async-await-eb148164a9c8 under "Pitfall 1: not awaiting"

Node.js request function return data

I have gone through questions about returning data from a node JS request call. A common mistake is assuming statements are executed line by line or synchronously, which is not the case here. A question of this type: How to get data out of a Node.js http get request.
My question is a bit different. I have written a function getNumber() which returns the number of results for given query. I am wondering how I return a value retrieved by the callback function? So for instance:
function getNumResults() {
Request(url, function(response) {
var responseJSON = JSON.parse(body);
return(responseJSON.results.count);
});
}
function Request(URL, callback) {
request(URL, function(error, response, body) {
console.log('URL: ', URL);
console.log('error: ', error);
console.log('statusCode: ', response && response.statusCode);
console.log('body: ', body);
callback(body);
});
}
What if I want getNumResults() to return responseJSON.results.count? How could I do this?
What if I want getNumResults() to return responseJSON.results.count? How could I do this?
You can't directly return an async value from getNumResults(). You just can't. The function returns long before the value is even available. It's a matter of timing. That's how async responses work. They finish some indeterminate time in the future, but they are non-blocking so the rest of your Javascript continues to run and thus the function returns before the result is even available.
The ONLY way to get the result out is with a callback of some kind. That applies to both your Request() function and to our getNumResults() function. Once a result is asynchronous, nobody in the calling chain can escape that. Async is infectious and you can never go from async back to synchronous. So, if your getNumResults() wants to get the value back to its caller, it will either have to accept a callback itself and call that callback when it gets the value or it will have to return a promise that is resolved with the value.
Here's how you could do this using promises (which are the future of async development in Javascript):
// load a version of the request library that returns promise instead of
// taking plain callbacks
const rp = require('request-promise');
function getNumResults(url) {
// returns a promise
return rp(url).then(body => {
// make the count be the resolved value of the promise
let responseJSON = JSON.parse(body);
return responseJSON.results.count;
});
}
Then, you would use getNumResults() like this"
getNumResults(someURL).then(count => {
// use the count result in here
console.log(`Got count = ${count}`);
}).catch(err => {
console.log('Got error from getNumResults ', err);
});
FYI, I think you can also get the request() library to parse your JSON response for you automatically if you want by setting an appropriate option {json: true}.
EDIT Jan, 2020 - request() module in maintenance mode
FYI, the request module and its derivatives like request-promise are now in maintenance mode and will not be actively developed to add new features. You can read more about the reasoning here. There is a list of alternatives in this table with some discussion of each one. I have been using got() myself and it's built from the beginning to use promises and is simple to use.

Resources