How to run multiple request with axios without waiting it finish - javascript

I want to make multiple requests with Axios without waiting it finish one on one.
what i want to do is, even when the first request is waiting, i want the second request is keep proccess and send the return, i dont want to waiting the first request because it will take long time..
async sendLog() {
setTimeout(() => {
if (this.proccessData === true) {
$nuxt.$axios.post('http://localhost/api/log/procreate', {logFile: this.form.logName})
.then((res) => {
this.sendLog();
})
}
}, 1000);
},
async addServer() {
$nuxt.$axios.post('http://localhost/api/servers/create', this.form)
.then((res) => {
this.proccessData = false;
}
}
But this code will run the next request when the current request is finished.

const foo = async() => {
const p1 = $nuxt.$axios.post();
const p2 = $nuxt.$axios.post();
const [res1, res2] = await Promise.all([p1, p2]);
// do with res1 and res2
}
see Promise.all

Not really sure if I understand your question correctly. If you want sendLog to be processed multiple times without waiting the previous one to finish, you might choose to use interval as following
async sendLog() {
setInterval(() => {
if (this.proccessData === true) {
$nuxt.$axios.post('http://localhost/api/log/procreate', {
logFile: this.form.logName
});
}
}, 1000);
}

Related

Why on printing I get value of null from API call in Loop

COIN LIST is an array of crypto coins(["BTCUSDT",...]). I try to get the price using getPriceAction and RSI from getRSI and these two functions are working when I try to console DATA. But when I try to print the response after the completion of the loop. It prints the empty array and the length is 0 of this array. I want to store the DATA object (consisting of SYMBOL, closing price and RSI) as an element in the response array
import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";
async function main() {
try {
let response = await [];
await COIN_LIST.forEach((element, i) => {
setTimeout(() => {
let data = { symbol: element };
getPriceAction(element, "4h").then((res) => {
data.closingPrice = res;
getRSI(res).then((res) => {
data.RSI = res.reverse();
data.closingPrice = data.closingPrice.reverse();
response.push(data);
console.log(data)
});
});
}, i * 1000);
});
console.log(response);
} catch (error) {
console.log(error.message);
}
}
main();
If you want to use async/await properly for your code, then use async/await, don't use .then/.catch as well
Some notable changes
there is no setTimeout of increasing seconds ... just waiting 1 second after one result before getting the next - far cleaner, and if one request happens to take a lot longer, you won't end up with two requests at once (which may be an issue if the API is rate limited)
no .then ... use async/await OR .then/.catch - very rare to need both in the one function
don't use forEach with async/await ... it never does what you want, and creating an array of Promises inside a .forEach is extremely naive, you may as well use .map instead! then you can await Promise.all(xxx.map(.....)) - but that's useful for concurrent requests, not so much for serial requests like your code does
import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";
async function main() {
try {
const wait = (ms) => new Promise(resolve => setTimeout(resolve, 1000));
let response = []; //---> don't need that `await`
for (let element of COIN_LIST) {
let data = { symbol: element };
data.closingPrice = await getPriceAction(element, "4h");
const res = await getRSI(data.closingPrice);
data.RSI = res.reverse();
data.closingPrice = data.closingPrice.reverse();
response.push(data);
console.log(data);
await wait(1000);
}
console.log(response);
} catch (error) {
console.log(error.message);
}
}
main();
the await wait(1000) could be tweaked depending on the rate limiting of the API ... if the rate limit applies to when the request is made, you could make a function that is smart about the delay between requests.
The code this way assumes the rate limit is based on the period between previous response to next request.
After the completion of the loop, the promises didn't get resolved yet, that's why it print an empty array.
One way to achieve what you need is using await for(...), or wait for all promises to be resolved, and then print the results.
import { COIN_LIST } from "./COIN_LIST.js";
import { getPriceAction } from "./PRICE_ACTION.js";
import { getRSI } from "./RSI.js";
async function main() {
try {
let response = []; //---> don't need that `await`
const promises = []; //---> array of promises
COIN_LIST.forEach((element, i) => {
setTimeout(() => {
let data = { symbol: element };
const promise = getPriceAction(element, "4h").then((res) => {
data.closingPrice = res;
getRSI(res).then((res) => {
data.RSI = res.reverse();
data.closingPrice = data.closingPrice.reverse();
response.push(data);
console.log(data)
});
});
promises.push(promise) //---> save the reference to a promise
}, i * 1000);
});
await Promise.all(promises) //---> await for all promises to be resolved, then print the result
console.log(response);
} catch (error) {
console.log(error.message);
}
}
main();

How can I postpone timeouterror by async programming?

I'm reviewing a React test, and I have a problem with asynchronous programming.
The requirements are:
It takes 7 minutes to get returned response after requesting data. But, when the response is delayed for 30 seconds, a timeout error will occur.
Check the API specs, fulfill these requirements:
Use the API that checks the data request progress and make it wait for response.
Check the progress every second.
And the API is:
import { rest } from 'msw';
export function handlers() {
return [
rest.get('/api/data', getData),
rest.get('/api/data/progress', getDataProgress),
];
};
const getData = async (req, res, ctx) => {
let wait = req.url.searchParams.get('wait');
if (wait !== 'no') {
wait = 'yes';
}
try {
startNewGetData();
if (wait === 'yes') {
await Promise.race([waitLastGetData, timeout(minutes(7)), timeoutError(minutes(0.5))]);
}
return res(ctx.status(200));
} catch {
return res(ctx.status(500));
}
};
const getDataProgress = (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
hasFinished: hasGetDataFinished,
})
);
};
let waitLastGetData = undefined;
let hasGetDataFinished = false;
function startNewGetData() {
hasGetDataFinished = false;
waitLastGetData = new Promise(resolve => setTimeout(resolve, minutes(3)));
waitLastGetData.then(() => (hasGetDataFinished = true));
}
I don't even know what I should first touch. Could you please tell me what I should do to fulfill those requirements?
You might not understand my English well because of my short English, sorry for that.

How can I use promises in an infinite loop with delay?

require("./getSongFromSpotify")().then(a => {
require("./instify")(a.artist,a.name).then(r => {
if (r.status === "ok"){
console.log("saved")
}else{
console.log("Instagram API have a problem!")
}
}).catch((r) => {console.error(r)})
}).catch((r) => {console.error(r)})
I need to execute this code in an infinite loop with 2000ms delay. How can I do this?
First of all, stop requiring modules for the each execution. Let's declare those separately, this will also make the code more clear and readable:
const getSong = require('./getSongFrompotify');
const instify = require('./instify');
Now let's write a function which we will call recursively after two seconds passed from the previous execution finish and the promisified timer:
function waitFor(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
})
}
function doJob() {
return getSong()
.then(song => instify(song.artist, song.name))
.then(result => {
if (result.status === 'ok') {
console.log('saved');
} else {
console.log('Problem!');
}
}) // no need to have 2 separate 'catch'
.catch(err => console.error(err)) // all errors fall here
.finally(() => waitFor(2000)) // anyway wait 2 seconds
.then(() => doJob()); // and run all again
}
Now, we simply need to call it:
doJob();
Note, that this approach will result in endless loop (as you asked for), but I think you'll probably need to setup some additional variable/flag which will be checked before of each iteration in order to be able stop it.
With async await syntax, this can be made to look quite straightforward:
const getSongFromSpotify = require("./getSongFromSpotify");
const instify = require("./instify");
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
async function keepPolling() {
while (true) { // forever (or until rejection)
let song = await getSongFromSpotify();
let result = await instify(song.artist, song.name);
if (result.status === "ok") {
console.log("saved");
} else {
console.log("Instagram API has a problem!");
}
await delay(2000);
}
}
keepPolling().catch(console.error);

Async request in react-redux using async/await

I'm new to React and I'm trying to make an Api call to a server then using this this data in my component.
I'm trying to use async await to handle asynchronous
const onNotifReceived = async (res) => {
var updatedQueue = res.updatedQueue;
updatedQueue["queueNewState"] = await getContactDetails(authClient, res.updatedQueue.queueNewState);
console.log(JSON.parse(JSON.stringify(updatedQueue)))
notifyQueue(updatedQueue); // redux dispatcher
}
I notice that console.log(JSON.parse(JSON.stringify(updatedQueue))) is run before other console.logsinside the function getContactDetails.
But as I know await should wait for the response before passing to the next line which is not the case and the problem that I'm not getting updatedQueue["queueNewState"] new state.
Maybe getContactDetails() do not return a promise, but there are delayed operations in.
async function xd() {
await xdd();
console.log("after xdd");
}
function xdd() {
setTimeout(() => {
console.log("1000 later");
}, 1000);
}
xd();
// after xdd
// (after 1 second)
// 1000 later
async function xd() {
await xdd();
console.log("after xdd");
}
function xdd() {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("1000 later");
resolve();
}, 1000);
});
}
xd();
// (after 1 second)
// 1000 later
// after xdd
For first situation, xdd runs before console.log("after xdd");, but console.log("1000 later"); will comes out 1 second later.

How to fix setTimeout behavior over HTTP requests?

On my client app, I'm using Socket IO to check for unread events. I make a request to my backend, which sets a timeout of 5 seconds, then proceeds to check for unread events and sends any back.
// client
socket.on("response", ({ mostRecentMessages }) => {
// do some stuff first
socket.emit("listenForNew", { userId, currentMessagesFromEveryone });
})
// backend
socket.on("listenForNew", ({ userId, currentMessagesFromEveryone }) => {
if (currentMessagesFromEveryone && userId) {
const { MostRecentMessages } = require("./constants/models");
const filteredIds = [];
currentMessagesFromEveryone.forEach(message => {
filteredIds.push(message.conversation._id);
});
console.log("Entered!");
setTimeout(async () => {
const mostRecentMessages = await MostRecentMessages.find({
to: userId,
date: { $gt: connectedUsersAllMessages[userId].timeIn },
conversation: { $nin: filteredIds }
}).populate("to from conversation");
allMessagesSocket.sockets.connected[
connectedUsersAllMessages[userId].socketId
].emit("response", {
mostRecentMessages
});
}, 5000);
}
});
At first, it works fine. It prints Entered! one time for about 4, 5 requests. Then on the 6th, it starts to print Entered! twice.
Why is this happening and what am I doing wrong?
I'm in favor of the below approach:
Wait for X seconds (5 in our use case)
Call an async operation (execution time in unknown)
Wait until async execution complete
Wait for another X seconds before executing the next call
Implementation may be something like that:
const interval = 5000;
function next() {
setTimeout(async () => myAsyncOperation(), interval);
}
function myAsyncOperation() {
const mostRecentMessages = await MostRecentMessages.find({
to: userId,
date: { $gt: connectedUsersAllMessages[userId].timeIn },
conversation: { $nin: filteredIds }
}).populate("to from conversation");
allMessagesSocket.sockets.connected[
connectedUsersAllMessages[userId].socketId
].emit("response", () => {
mostRecentMessages();
next(); // "next" function call should be invoked only after "mostRecentMessages" execution is completed (or a race condition may be applied)
});
}
next();
I haven't compiled this code but I hope that the concept is clear

Categories