I have two .js files like:
index.js:
app.get("/testing", (req, res) => {
testAsyncFunction().then((resolvedData) => {
res.send(resolvedData);
});
})
and server.js:
const asyncFunction = () => {
return new Promise((res) => {
setTimeout(() => {
res('resolved');
},3000 )
})
}
const testAsyncFunction = () => {
return new Promise(async (res) => {
const result = await asyncFunction();
return res(result);
})
}
and this is working as intended but if I change the testAsyncFunction(so that I don't create a new promise) to something like this:
const testAsyncFunction = async () => {
const result = await asyncFunction();
return result;
}
and in index.js:
app.get("/testing", (req, res) => {
res.send(testAsyncFunction());
})
I'm getting an empty object because it isn't waiting for 3 seconds, what am I missing in the latter case? I want to avoid creating a new Promise just to wait for another promise.
UPDATE
I changed the testAsyncFunctionto something like this:
const testAsyncFunction = () => {
asyncFunction().then((result) => {
return result;
})
}
Even though the above function. isn't an async function why do I still have to wait for it in the index.js..I'm assuming the returned value won't be a promise in this case so that's the part I'm confused about.
so that I don't create a new promise that's how it should be, other way is an antipattern. However, when a function returns a promise you need to wait for the same
app.get("/testing", async (req, res) => {
let obj = await testAsyncFunction()
res.send(obj );
});
OR
app.get("/testing", (req, res) => {
testAsyncFunction().then((obj) => {
res.send(obj );
})
});
const testAsyncFunction = async () => {
const result = await asyncFunction();
return result;
}
async functions always return promises. So this is equivalent to:
const testAsyncFunction = () => {
return asyncFunction();
}
I want to avoid creating a new Promise just to wait for another promise.
So just use the existing promise:
app.get("/testing", (req, res) => {
asyncFunction().then((resolvedData) => {
res.send(resolvedData);
});
})
const asyncFunction = () => {
return new Promise((res) => {
setTimeout(() => {
res('resolved');
},3000 )
})
}
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 11 months ago.
I found different solutions here, but none worked for me. I have this simple code:
const Element = () => {
async function getEndData() {
const data = (await getEnd());
return data;
}
}
const getEnd = async () => {
return await axios.get('http://localhost:8080/end').then(res => res.data);
}
And it always return a Promise "pending" with inside a [[PromiseResult]] with the value i need, when i call getEndData().
I tried also to call directly getEnd() removing the then(), returning only the data, but nothing. If i print res.data in console.log, it will return the right value i need.
this should work:
const Element = () => {
async function getEndData() {
const data = await getEnd();
return data;
}
}
const getEnd = async () => {
const response = await axios.get('http://localhost:8080/end');
return response;
}
I'm not sure you are doing it the right way. You can try this:
const Element = () => {
return async function getEndData() {
const data = await getEnd();
return data;
}
}
const getEnd = () => {
return new Promise((resolve, reject) => {
axios.get('http://localhost:8080/end')
.then(res => {
resolve(res.data)
})
.catch(err => {
reject(err);
})
})
}
Also, What is the use of element function if you are not returning anything.
your getEndData() in returning a promise . add await or then where ever you are receiving the getEndData() response .
// const Element = () => {
async function getEndData() {
const data = (await getEnd());
return data;
}
// }
const getEnd = async () => {
return await axios.get('http://localhost:8080/end').then(res => res);
}
async function callEndData(){
let x = await getEndData()
console.log(x)
}
callEndData()
since it is returning promise and you are not using await or then it is showing promise pending
why do you need Element() ?
In case you need to call ELement function and also wants the data part of response you can try like this .
const Element = async() => {
async function getEndData() {
return await getEnd();
}
let fromEndData = await getEndData()
return fromEndData
}
const getEnd = async () => {
return axios.get('http://localhost:8080/end').then(res => {
return res.data
});
}
async function callEndData(){
let x = await Element()
console.log(x)
}
callEndData()
in console.log(x) i am getting the value being passed .
I have three async functions but the third function is running before the second one resolves. What is wrong here?
async function getSet () {
//get settings from asyncstorage and setstate
}
async function pairs () {
//fetch data and set another state
}
async function fetchIt () {
//fetch another data and set a third state
}
useEffect(() => {
getSet()
.then(pairs())
.then(fetchIt())
.then(() => {
setLoading(false);
});
}, []);
fetchIt() is running before pairs()
The calls aren't chained properly. To make it simpler use async await:
useEffect(() => {
(async function () {
await getSet();
await pairs();
await fetchIt();
setLoading(false);
})();
}, []);
If each call depends on the result of the last it looks like
const r1 = await getSet();
const r2 = await pairs(r1);
// etcetera
You haven't chained the 'then's properly. They must return a promise as well. Read more here.
const getSet = async() => {
//get settings from asyncstorage and setstate
return new Promise((resolve, reject) => {
resolve('getSet');
});
}
const pairs = async() => {
//fetch data and set another state
return new Promise((resolve, reject) => {
resolve('pairs');
});
}
const fetchIt = async() => {
//fetch another data and set a third state
return new Promise((resolve, reject) => {
resolve('fetchIt');
});
}
getSet()
.then(response => {
console.log(response);
return pairs();
})
.then(response => {
console.log(response);
return fetchIt();
})
.then(response => {
console.log(response);
// setLoading(false);
});
I'm learning JavaScript and I'm learning about Promises. I'm having a hard time to understand the following code:
const button = document.querySelector("button");
const div = document.querySelector("div");
const setText = (text) => {
div.textContent = text
}
const checkAuth = () => {
return new Promise((resolve, reject) => {
setText('Checking Auth...')
setTimeout(() => {
resolve(true);
}, 2000);
});
};
const fetchUser = () => {
return new Promise((resolve, reject) => {
setText('Fetching User...');
setTimeout(() => {
resolve({ name: "Max" });
}, 2000);
});
};
button.addEventListener("click", () => {
checkAuth()
.then(
isAuth => {
if (isAuth) {
return fetchUser()
}
}
)
.then(
user => {
setText(user.name)
}
)
});
I understand the first two functions checkAuth and fetchUser, they return a resolved Promise after 2 seconds.
I can't really understand how does the event listener of button work. I see it calls checkAuth() and when executed, the div text of the HTML document changes to Checking Auth... for two seconds (until the function resolves successfully the Promise. When resolved, it enters into the .then() part of the code.
I'm struggling to understand where does isAuth and user come from. I feel like they are some implicit declaration of a function (called inside themselves?), it's looking really odd to me.
checkAuth() returns a promise and the value with which it resolves is passed to the callback function of checkAuth().then(...) which is then assigned to isAuth parameter.
In the case of user, it is the value with which the promise returned by checkAuth().then() is resolved. If the callback function of checkAuth().then(...) returns a non-promise value, user will be that non-promise value.
If the callback function of checkAuth().then() returns a promise, then user will be the value with which that promise, returned by the callback function, resolves.
Here's a simplified example that might help you understand how isAuth and user are assigned a value:
Promise.resolve(true)
.then(isAuth => {
console.log("isAuth: " + isAuth);
return { name: "John Doe" };
})
.then(user => console.log(user));
Here is the explanation:
const button = document.querySelector("button");
const div = document.querySelector("div");
const setText = (text) => {
div.textContent = text
}
const checkAuth = () => {
return new Promise((resolve, reject) => {
setText('Checking Auth...')
setTimeout(() => {
resolve(true); // The return value when the promise resolves which is in this case is `true`;
}, 2000);
});
};
const fetchUser = () => {
return new Promise((resolve, reject) => {
setText('Fetching User...');
setTimeout(() => {
resolve({ name: "Max" }); // Here when the promise resolves it is returning `{ name: "Max" }`;
}, 2000);
});
};
button.addEventListener("click", () => {
checkAuth()
.then(isAuth => { // This is an arrow function, you can see we are accepting the `isAuth` parameter;
if (isAuth) { // Regular if...
return fetchUser() // And the this also returns an promise
}
}
)
.then(user => { // Which is resolved here, And the user is the `{ name: "Max" }`;
setText(user.name)
}
)
});
isAuth is returned by checkAuth and user is returned by fetchUser.
I'll re-write this in async/await format. You can compare to make better sense of it.
const delay = (time) => new Promise(res => setTimeout(res(), time));
const checkAuth = async () => {
setText('Checking Auth...');
await delay(2000);
}
const fetchUser = async () => {
setText('Fetching User...');
await delay(2000);
}
const executeOrder = async () => {
const isAuth = await checkAuth();
if (isAuth) {
const user = await fetchUser();
setText(user.name)
}
}
button.addEventListener("click", executeOrder);
I would like to use multiply times async foo function in mocha tests and try to do it like this:
describe('This test', () => {
const foo = async () => {
const wrapper = mount(Component);
const button = wrapper.find('button');
button.simulate('click');
wrapper.update();
await new Promise(res => setTimeout(() => {
res('');
}, 0));
wrapper.update();
return wrapper;
};
it('should pass 1', () => {
const wrapper = foo();
console.log(wrapper.debug());
});
it('should pass 2', () => {
const wrapper = foo();
console.log(wrapper.debug());
});
});
But then output is
TypeError: wrapper.debug is not a function
This works fine without async await.
Can you help resolve it?
It looks like solution is:
describe('This test', () => {
const foo = async () => {
const wrapper = mount(Component);
const button = wrapper.find('button');
button.simulate('click');
wrapper.update();
await new Promise(res => setTimeout(() => {
res('');
}, 0));
wrapper.update();
return wrapper;
};
it('should pass 1', async () => {
await foo();
console.log(wrapper.debug());
});
it('should pass 2', async () => {
await = foo();
console.log(wrapper.debug());
});
});
#CodeJoe is correct,
use async await for resolving this. async always returns a promise, so await functions are there to wait for those promises to resolve or reject.
If some thing is returned from async functions, then await keyword is used to call that function and wait for the promise to resolve or reject. await is always meant for WAIT
describe('This test', () => {
const foo = async () => {
return new Promise(async (resolve, reject) => {
const wrapper = mount(Component);
const button = wrapper.find('button');
button.simulate('click');
wrapper.update();
await new Promise(res => setTimeout(() => {
res('');
}, 0));
wrapper.update();
resolve(wrapper);
})
};
it('should pass 1', () => {
const wrapper = await foo();
console.log(wrapper.debug());
});
it('should pass 2', () => {
const wrapper = await foo();
console.log(wrapper.debug());
});
});
Also, always try to return something from your async function to avoid resolve conflicts. If there is not something to resolve, make a new promise and return resolve.
In promises instances/ async promises, use the following according to requirement -
return resolve()
return resolve(wrapper)
return reject()
return reject('Reject message')
return reject(new Error('Error message')
Im trying to return a value from a Promise in async-await form and use it in another function in another file, but I do have problem because my Promise doesnt return any value.
When im trying to console.log('website') it returns me undefined immediately (it's like the value is not being fetched at all from API services). I dont know what im doing wrong, I really love to learn about Promises and Async-Await but each time im trying to work with them im getting more confused.
const dns = require('dns')
const iplocation = require("iplocation").default;
const emojiFlags = require('emoji-flags');
const getServerIPAddress = async (server) => {
return new Promise((resolve, reject) => {
dns.lookup(server, (err, address) => {
if (err) throw reject(err);
resolve(address);
});
});
};
const getServerLocation = async (server) => {
const ip = await getServerIPAddress(server)
iplocation(ip).then((res) => {
const country = emojiFlags.countryCode(res.countryCode)
const result = `Location: ${country.emoji} ${country.name}`
return result
})
.catch(err => {
return `Location: Unknown`
});
}
(async function() {
console.log(await getServerLocation('www.google.com'))
})()
module.exports = {
getServerLocation
}
It is really important for me to get result from this function first, then use its value in another function. I wish you could give me tips on how to do tasks asynchronously.
You're clearly using async so it's not apparent why you're using then as well. If you use then then you must return the promise as well in order to preserve the promise chain:
const getServerLocation = async (server) => {
const ip = await getServerIPAddress(server)
return iplocation(ip).then((res) => {
const country = emojiFlags.countryCode(res.countryCode)
const result = `Location: ${country.emoji} ${country.name}`
return result
})
.catch(err => {
return `Location: Unknown`
});
}
Otherwise just async this:
const getServerLocation = async (server) => {
const ip = await getServerIPAddress(server)
let res = await iplocation(ip);
const country = emojiFlags.countryCode(res.countryCode)
const result = `Location: ${country.emoji} ${country.name}`
return result
}
const getServerLocation = async (server) => {
const ip = await getServerIPAddress(server)
//you need to return
return iplocation(ip).then((res) => {
const country = emojiFlags.countryCode(res.countryCode)
const result = `Location: ${country.emoji} ${country.name}`
return result
})
.catch(err => {
return `Location: Unknown`
});
}