Chaining three different async functions - javascript

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);
});

Related

axios.get always returning a Promise<Pending> [duplicate]

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 .

What is this function doing in JavaScript?

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);

Async module returning promise [object Promise]

I am trying to export the value with instrument variable. however data is returning as [object Promise] than object. How can I assign module variable with the final result rather than the promise object.
var instruments = {
data: async () => {
return new Promise((resolve, reject) => {
/// Respond after retrieving the data
resolve({result : "...." }
);
}
}
var symbols = async () => {
const res = await instruments.data();
return res;
}
module.exports.instrument = symbols().then((data) => {
console.log('data');
return data;
}).catch((e) => {
console.log('error');
return {}
});
It looks like you want a singleton cache. Here is a basic implementation
cache.js
let data = {}
module.exports = {
getData: () => {
return data
},
setData: newData => {
data = newData
return
},
}
No need for async here. I would separate this code with the code that retrieves data.
fetchData.js
const cache = require('./cache')
const fetchData = () => {} // fetch data code here
fetchData().then(data => {
cache.setData(data)
})
try this
var instruments = {
data: () => {
return new Promise((resolve, reject) => {
/// Respond after retrieving the data
resolve({result : "...." });
}
}
var symbols = async () => {
const res = await instruments.data();
return res;
}
module.exports.instrument = symbols;
then import instrument method to call and then call
const instrument = require("./filepath");
instrument().then((data) => {
console.log('data');
}).catch((e) => {
console.log(e);
});
If your async function instruments.data() called, it'll await return Promise.
just append await at return for your expected result.
var instruments = {
data: async () => {
return await new Promise((resolve, reject) => {
// Respond after retrieving the data
resolve({result : "...." });
}
}
or remove async. it's same as above.
var instruments = {
data: () => {
return new Promise((resolve, reject) => {
// Respond after retrieving the data
resolve({result : "...." });
}
}

How can I avoid using another promise in my case?

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 )
})
}

Un-nest JavaScript Firestore Functions

How can I rewrite this code to not be nested in itself? I also need access to the values obtained in the previous functions calls.
return docRef2.doc(`/users_stripe/${context.params.userID}`).get()
.then(snapshot => {
console.log("augu", snapshot);
return stripe.customers.createSource( jsonParser(snapshot._fieldsProto.id, "stringValue"),
{ source: jsonParser(snap._fieldsProto.token, "stringValue") },
function(err, card) {
console.log("listen people", card);
return docRef2.doc(`/users_stripe/${context.params.userID}/ptypes/ptypes`)
.set(card);
});
})
I am not sure what your code is doing here. I tried to write a pseudo/sample code that might give you an idea.
My code is not checked, so might contain problem.
let fun1 = () => {
return new Promise((resolve, reject) => {
docRef2.doc('/route').get().then(snapshot => {
if( snapshot ) resolve(snapshot);
else reject(snapshot);
})
})
}
let fun2 = (snapshot) => {
return new Promies((resolve, reject)=>{
stripe.customers.createSource(jsonParser(snapshot._fieldsProto.id, "stringValue"),
{ source: jsonParser(snap._fieldsProto.token, "stringValue") },
function (err, card) {
if (err) reject(false);// or whatever you wanna return
else resolve(card);
});
})
}
async function fun(){
let res1 = await fun1(); // Should contain snapshot
let res2 = await fun2(res1); // Should contain card
return docRef2.doc(`/users_stripe/${context.params.userID}/ptypes/ptypes`)
.set(card);
}

Categories