How can I rewrite the Axios promise module with only async/await syntax? Please I'm new to Axios & promise, async syntax => what should i put inside the .push() ?
const axios = require("axios");
const _ = require("lodash");
const queue = require("queue");
// To control the request rate
const GetDataQueue_B = queue({ autostart: true, concur: 1 });
// someone's codes
const getDATA = () => {
return new Promise((resolve, reject) => {
// To make sure only one request call
GetDataQueue_B.push(
async () => {
try{
const res = await axios.get(`${whichAPI}/api`);
resolve(
_.map(
_.get(res, "data.infor"),
obj => ({
quotes:obj.quotes,
author:boj.author,
})
)
);
}catch(e) {reject(e);console.log(e);}
}
);
});
below is my try: => what should i put inside the .push() ?
const getDATA_1 = async () => {
try{
const res = await axios.get(`${whichAPI}/api`);
const data = _.map(
_.get(res, "data.infor"),
obj => ({
quotes:obj.quotes,
author:boj.author,
})
)
GetDataQueue_B.push(); // => what should i put inside the .push() method?
return data;
}catch(e){console.log(e);}
};
queue isn't the best choice here for clean code because while it allows pushing functions that return a promise, it itself doesn't return a promise, so you'd always be forced to use new Promise at some point and resolve it in its success callback or at the end of your own code. I guess that's the main reason why you are stuck with improving this code.
I recommend using p-limit instead. It works like this:
const pLimit = require("p-limit");
const myQueue = pLimit(5); // Allow only 5 things running in parallel
const promise = myQueue(async () => { /* stuff */ });
// promise will resolve once the passed function ran, and will return its
// result.
So, the code then looks like this:
const axios = require("axios");
const _ = require("lodash");
const pLimit = require("p-limit");
// To control the request rate
const GetDataQueue_B = pLimit(1);
// someone's codes
const getDATA = () => GetDataQueue_B(async () => {
const res = await axios.get(`${whichAPI}/api`);
return _.map(
_.get(res, "data.infor"),
obj => ({
quotes: obj.quotes,
author: boj.author,
})
)
);
});
I removed the try/catch because in the new version it wouldn't really do anything - an error here would reject the resulting promise anyway.
Side note: Using lodash is unnecessary here. It's always good to keep dependencies at a minimum and use built-in functionality instead. We could rewrite the code without lodash as follows:
const axios = require("axios");
const pLimit = require("p-limit");
// To control the request rate
const GetDataQueue_B = pLimit(1);
// someone's codes
const getDATA = () => GetDataQueue_B(async () => {
const res = await axios.get(`${whichAPI}/api`);
return res.data?.infor?.map(({ quotes, author }) => ({ quotes, author })) ?? [];
});
If you were sure that the res.data.infor array exists and you also wouldn't care about extra properties other than quotes and author in the result, this could be simplified even further:
const getDATA = () => GetDataQueue_B(async () => {
const res = await axios.get(`${whichAPI}/api`);
return res.data.infor;
});