Reputation: 111
I have code like below. The actual function is querying historical data from an API. Each item in the array relates to, for example, a company so each iteration is returning historical data about that company. The historical data function is within a setTimeOut function in order to regulate the number of requests as the API only allows a certain number in a certain period of time.
Each time you make a request your allowance goes down (which is what the getRemainingAllowance promise is for. So I'm trying to break the loop if the remaining allowance falls below 2000.
Is there a way I can return the resolved value within the promise so that I can use it within the if statement to break the loop?
I also tried result = resolvedValue (without the var) to make it global but I was still getting undefined - I've also read global variables aren't always the right approach).
for (var i = 0; i < arr.length; i++) {
const historical = require('./historic')
getRemainingAllowance().then((resolvedValue) => {
var result = resolvedValue
})
if (result < 2000) {
break
} else {
setTimeout(function() {
historical.getHistoric(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
}, 3000 * (i + 1))
}
}
Upvotes: 1
Views: 172
Reputation: 29282
First of all, move the require
statement out of the loop body and secondly, you could re-write your code using async-await
syntax as shown below. You also don't need setTimeout()
to add a delay between requests.
for (var i = 0; i < arr.length; i++) {
const result = await getRemainingAllowance();
if (result < 2000) {
break;
} else {
historical.getHistoric(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
await sleep(2); // delay of 2 seconds
}
}
sleep()
function takes number of seconds as an argument and returns a Promise
that resolves after number of seconds passed as an argument.
function sleep(seconds) {
return new Promise((resolve, reject) => {
setTimeout(resolve, seconds * 1000);
});
}
Keep in mind that await
keyword can only be used inside an async
function.
Upvotes: 2
Reputation: 1469
I think the best approach here would be using async/await as it is cleaner.
async function doWork() {
for (var i = 0; i < 100; i++) {
const result = await getRemainingAllowance();
// use your returned value
}
}
You could do it using classic promises too, but it's a little bit more weird:
var counter = 0;
function doWork() {
getRemainingAllowance().then((result) => {
// process your result
counter++;
if (counter < 100) {
doWork(); // do it again until you hit the limit
}
});
}
Upvotes: 1