user2547766
user2547766

Reputation: 111

Using resolve value from promise in if statement of for loop

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

Answers (2)

Yousaf
Yousaf

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

Mihail Feraru
Mihail Feraru

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

Related Questions