2

I have an asynchronous function which makes a request, makeRequest(): Promise<string>. Basically, I want to make a way of queuing calls to this function so that requests are only being made one at a time.

async function queueRequest(): Promise<string> {
  await ... // some code to make sure all previous requests have already been completed
  const result = await makeRequest();
  return result;
}

What is the best way to achieve something like this?

Thanks in advance

2 Answers 2

2

To do it you need to use an array where you shift a task and you push the new incoming task.

I would use fastq to avoid to reimplement all the logic to manage a queue data structure.

Here an example:


const queue = require('fastq')(worker, 1)

function worker (params, cb) {
  console.log('Executing ', params)
  setTimeout(() => {
    cb(null, { i: params })
  }, Math.random() * 100)
}

function makeRequest (params) {
  return new Promise((resolve, reject) => {
    queue.push(params, function (err, result) {
      if (err) { return reject(err) }
      resolve(result)
    })
  })
}

async function queueRequest (index) {
  const result = await makeRequest(index)
  // manage the result
  return result
}

for (let i = 0; i < 10; i++) {
  queueRequest(i)
}

Sign up to request clarification or add additional context in comments.

Comments

1

This snippet is from the MDN page on Promises. They have a couple more examples directly following the one I have below too in order to expand a little upon it.

Sequential composition is possible using some clever JavaScript:

[func1, func2, func3].reduce((p, f) => p.then(f), Promise.resolve())
.then(result3 => { /* use result3 */ });

Basically, we reduce an array of asynchronous functions down to a promise chain equivalent to: Promise.resolve().then(func1).then(func2).then(func3);

Here is a good article on using reduce() to achieve this goal of sequential Promises. It does a good job of walking through it and explaining each step better than the MDN docs.

1 Comment

How would I go about this in a way in which each queueRequest() call returns the result when it eventually comes, and I can queue a new request at any point in time?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.