jessetane / queue

Asynchronous function queue with adjustable concurrency
MIT License
759 stars 66 forks source link

Delay between Jobs #81

Open mado-bohsali opened 2 years ago

mado-bohsali commented 2 years ago

How do I set a delay between jobs in a queue? My jobs represent API calls

jessetane commented 2 years ago

Use setTimeout to execute the job's callback / resolve the promise it returned

PlanetIrata commented 2 years ago

Hi Jesse, could you provide an example code ? I’d like to use ˋqueueˋ to send e-mails and need to throttle the process to not exceed 4 sendings per seconds. Thx.

harveysanders commented 2 years ago

@PlanetIrata I know this is a month old, but maybe it will be helpful to the next person. As @jessetane stated, you can use setTimeout to delay the invocation of the job's callback. When q.concurrency === 1, the queue will run the next job after the current job's callback is called.

const q = queue({ concurrency: 1, autostart: true });

function sendThrottledEmail(email) {
  q.push((cb) => {
    _sendEmail(email);
    setTimeout(cb, 250);
  });
}

You can also use a Promise. If sendEmail fails, an error event with be emitted on q.

const q = queue({ concurrency: 1, autostart: true });

function sendThrottledEmail(email) {
  const delay = 1000 / 4;

  q.push(
    () =>
      new Promise((resolve, reject) => {
        _sendEmail(email)
          .then(() => setTimeout(resolve, delay))
          .catch((err) => setTimeout(() => reject(err), delay));
          // or fail immediately and run the next job
          // .catch(reject);
      })
  );
}
Chamuelm commented 2 years ago

Althugh the suggestions above may work - the right tool for your need will be a rate limiter / throttler, see this: https://www.npmjs.com/package/limiter