Here, plcs variable within try catch function need to be used outside. I am trying calling async function directly and storing in sync function, both doesn't work, first method shows undefined and next one returns null promise
const fetch = () =>{
const result=async()=>{
try {
const dbResult = await ftchplc();
plcs= dbResult.rows._array;
return plcs
} catch (err) {
throw err;
}
}
return result()
}
const sample = fetch()
console.log(sample)
const result=async()=>{
try {
const dbResult = await ftchplc();
plcs= dbResult.rows._array;
return plcs
} catch (err) {
throw err;
}
}
result()
const sample = result()
ALL async functions return a promise. So you will have to use await or .then() when you call an async function in order to get the resolved value.
async functions are useful INSIDE the function so you can use await internal to the function, but to the outside caller, it's still just a promise being returned. async functions to not turn an asynchronous result into a synchronous result. The caller of an async function still has to deal with an asynchronous response (in a promise).
For example:
async function fn() {
const dbResult = await ftchplc();
return dbResult.rows._array;
};
fn().then(sample => {
console.log(sample);
}).catch(err => {
console.log(err);
});
This assumes that ftchplc() returns a promise that resolves to your expected dbResult.
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
async/await always returns promise
(4 answers)
Closed 2 years ago.
I have a function getData in functions.js, when I called in another file, scripts.js it returns promise not an object.
//------ functions.js ------
export async function getData(arg1,arg2,arg3) {
...
let result = await fetch(proxyUrl + targetUrl, requestOptions)
.then(response => response.json())
.catch(error => console.log('error', error));
return result
}
When I call like this I get a Promise:
//------ scripts.js ------
import {getData} from './functions';
let result = getData(arg1,arg2,arg3)
console.log(result)
But even I called like this, I get an Error:
//------ scripts.js ------
import {getData} from './functions';
let result = awiat getData(arg1,arg2,arg3)
console.log(result)
"Uncaught SyntaxError: Unexpected reserved word"
getData is a async functions and returns a Promise and await is only allowed inside async function.
export async function getData(arg1,arg2,arg3) {
try {
const response = await fetch(proxyUrl + targetUrl, requestOptions)
return await response.json()
} catch(err) {
console.log(err)
throw err
}
}
import { getData } from './functions';
getData(arg1,arg2,arg3).then(result => {
console.log(result)
})
OR this way
import { getData } from './functions';
const print = async () => {
const result = await getData(arg1,arg2,arg3)
console.log(result)
}
print()
Instead of explicitly promise-based code with .then() and .catch(), use a try/catch block and an actual return statement in an async function, :
export async function getData(proxyUrl, targetUrl, requestOptions) {
try {
let response = await fetch(proxyUrl + targetUrl, requestOptions);
return response.json();
} catch (error) {
console.log('error', error);
}
}
Of course this function still returns a Promise. Every async function does. Promises never actually goes away, async/await only hides them. It's syntactic sugar. This is important: You cannot return a value from an asynchronous function, no amount of syntactic sugar can change that fact.
So when you call it, either await it in another async function
async function main() {
var data = await getData(...);
}
or use Promise semantics in a regular function:
function main() {
getData(...).then(data => ...);
}
I'm using a helper function (fetchGet) returning an asynchronous function that returns a promise (fetchWrapper).
Does this helper function need to be declared as asynchronous to itself return a promise?
My case here is using fetch, which needs to be awaited in my first function fetchWrapper (simplified here for readibility):
// returns a promise
async function fetchWrapper(url, method) {
const response = await fetch(url, {method: method});
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response;
}
async function fetchGet(url) {
return fetchWrapper(url, 'GET');
}
async function getSpecificData() {
return fetchGet('/a/specific/url');
}
Do I need to declare the fetchGet function as an asynchronous function as above, for it to return the promise?
Or could I just declare it as a normal synchronous function as below?
(that would be indeed the same case for the getSpecificData function)
function fetchGet(url) {
return fetchWrapper(url, 'GET');
}
Does a function need to be declared as asynchronous to return a promise?
No, not at all. In fact, promises were around long before async functions.
Your wrapper can be just:
function fetchGet(url) {
return fetchWrapper(url, 'GET');
}
You don't need async if you're not using await inside the function. You might choose to have it in order to flag up the asynchronous nature of the function, e.g., as in-code documentation (code hints in IDEs, etc.). But it isn't required.
Side note: You have a problem with fetchWrapper. It succeeds with the fulfillment value undefined if there's an HTTP error. That means code using it has to check the fulfillment value to see if it's undefined before using it. I'd recommend making HTTP errors errors (rejections):
async function fetchWrapper(url, method) {
const response = await fetch(url, {method: method});
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response;
}
Does this helper function need to be declared as asynchronous to itself return a promise?
No.
async functions always return promises, even if the return statement returns something that is not a promise. async functions let you manage other promises inside them using await
You can explicitly return a promise from any function.
You just need to declare a function as async when inside the function you going to await for a result, so both:
// returns a Promise because it's async (resolved with 'value')
async function fetchGet(url) {
const value = await fetchWrapper(url, 'GET');
return value;
}
// returns a Promise because fetchWrapper is a Promise
function fetchGet(url) {
return fetchWrapper(url, 'GET');
}
// returns a Promise, just because it's async
async function fetchGet(url) {
// nothing
}
// returns undefined
function fetchGet(url) {
// nothing
}
Work exactly the same for these callers:
fetchGet('url').then(value => {...})
const value = await fetchGet(url)
(Forgive me if the title is inaccurate to the problem this one is boggling the mind)
My application requires that I check a value from the request against the database. For this I created an asynchronous function to query the database:
async function checktoken(){
return prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
return(result)
})
}
I know that the database call on its own works:
prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
console.log(result) // returns true
})
In the function that fires at every request I try and call checktoken():
async function getUser(token){
var promise = await checktoken()
var result = promise
console.log(result) //undefined
};
Amending the function to include an explicit call to the database works but only when var promise = await checktoken() is defined before it:
async function getUser(token){
var promise = await checktoken() //When this is removed result1 is undefinded
await prisma.$exists.invalidtoken({token: "testtoken"}).then(result1 => {
console.log("inside db call: "+result1) // true
})
};
I think I have a fundamental misunderstanding of async/await but I am not sure exactly what I am missing.
EDIT:
I have updated my approach taking the advice I received and it still does not work. I am beginning to think my ORM is doing something weird:
async function test(token) {
const status = await prisma.$exists.invalidtoken({ token: token });
console.log(status);
return status;
}
test("123") //logs false (as it should)
async function getUser(token){
var status = await test(token) //logs undefined
console.log(status) //logs undefined
};
An async function requires an await. If you are using the promise.then() technique, then what you would want to do is return a new Promise(), and within the .then call back function resolve the promise
function checktoken() {
return new Promise((resolve,reject) => {
prisma.$exists.invalidtoken({token: "testtoken"}).then(result => {
doSomeOtherStuff();
resolve(result);
});
});
}
Is functionally the same as
async checktoken() {
await prisma.$exists.invalidtoken({token: "testtoken"});
}
I'm trying to make this code (a class method) returning a String.
async sign() {
const txt = 'ddddd';
const result = await crypto.createHash('md5').update(txt, 'binary').digest('hex');
return result;
}
The problem is that it ignores await and returns a Promise. This function's returned value is used as a HTTP request header, and while npmlog says it's
apisign: Promise { 'faaa3f1409977cbcd4ac50b5f7cd81ec' }
in network traffic caught by Wireshark I see
apisign: [object Promise]
How do I make return respecting await, or how should I write it so it returns a String?
You should not return the value of an async function as is, since it is a Promise
await for it before serializing it.
An async function always returns a Promise.
If you invoke sign() inside another function then you have to await for it and this requires making the caller function also an async function and so on and so forth.
Eventually, at the top-level code you have to use the regular .then().catch() syntax to wait for the Promise to settle:
sign()
.then((result) => {
// do something with the result (e.g. put it into the response header)
console.log(result);
})
.catch((err) => {
// something wrong happened and the Promise was rejected
// handle the error
console.log(`There was an error: ${err.message || err}`);
});
You will have to await the response of a async function.
const getURL = (title, page) => `https://jsonmock.hackerrank.com/api/movies/search/?Title=${title}&page=${page}`
const callService = async (title, page) => {
let response = await fetch(getURL(title, page));
return await response.json();
}
async function callApi() {
let data = await callService('spiderman', 1);
console.log(data.data.length);
}
callApi();
In my case , i am able to get the token but not the way i wanted ie i do not want to print promise pending and my output after running in tokenDisp.js is :
output: Promise { pending }
t5Npxk5FfnRTj8iHd8vyyfGxnhXR4KQf
login.js:
module.exports = async function doLogin() {
const token = await loginToken();
const myToken = JSON.parse(token);
return console.log(myToken);
};
tokenDisp.js:
const myToken = require('./login.js);
myToken();
Can someone help ?
All async functions return a promise and you still have to use .then() or await on the return value from the async function in order to use that. If you return a value from your async function, it will be the resolved value of the returned promise. If you throw an exception, the exception will be the reason for the rejection of the returned promise.
The use of await inside the function is a convenience INSIDE the async function. It does not magically make an asychronous operation into a synchronous one. So, your function returns a promise. To get the value out of it, use .then() on it.
module.exports = async function doLogin() {
const token = await loginToken();
const myToken = JSON.parse(token);
console.log(myToken);
return myToken; // this will be resolved value of returned promise
};
const myToken = require('./login.js);
myToken().then(token => {
// got token here
}).catch(err => {
console.log(err);
});
Note: your login.js module produces the same result as if it was written like this (without using async or await):
module.exports = function doLogin() {
return loginToken().then(token => {
const myToken = JSON.parse(token);
console.log(myToken);
return myToken; // this will be resolved value of returned promise
});
};