jhurliman / node-rate-limiter

A generic rate limiter for node.js. Useful for API clients, web crawling, or other tasks that need to be throttled
MIT License
1.5k stars 132 forks source link

Would this work with await? #52

Closed dbeja closed 6 years ago

dbeja commented 6 years ago

Hi,

I have something like this:

import {RateLimiter} from 'limiter';
const dynamoDBLimiter = new RateLimiter(10, 'second');
console.log('before removeTokens');
for(let contact_i = 0; contact_i < company.contacts.length; contact_i++) {
  dynamoDBLimiter.removeTokens(1, async function(err, remainingRequests) {
    console.log('adding contact');
    newContact = await addContact(contact_i);
    console.log('new contact added');
  });
}
console.log('end of removeTokens');

But the logs I get are like this:

before removeTokens
end of removeTokens
adding contact
new contact added

Am I doing something wrong? Thanks!

dbeja commented 6 years ago

Ok, figured it out. This is a callback so removeTokens wouldn't be waiting for the function to finish. I just added the rest of the code needed after getting the contact inside removeTokens callback and it's working fine!

jhurliman commented 6 years ago

You would need to wrap the callback-based API with a Promise to make it compatible with async/await. Something like this:

import {RateLimiter} from 'limiter';

main()

async function main() {
  const dynamoDBLimiter = new RateLimiter(10, 'second');
  console.log('before removeTokens');
  for(let contact_i = 0; contact_i < company.contacts.length; contact_i++) {
    await removeTokens(1, dynamoDBLimiter)
    console.log('adding contact');
    const newContact = await addContact(contact_i);
    console.log('new contact added');
  }
  console.log('end of removeTokens');
}

function removeTokens(count, limiter) {
  return new Promise((resolve, reject) => {
    limiter.removeTokens(count, (err, remainingRequests) => {
      if (err) return reject(err)
      resolve(remainingRequests)
    })
  })
}