Skip to main content
Removing unnecessary portion which undermines my answer.
Source Link
cmhteixeira
  • 967
  • 12
  • 22

What do you guys think of this attempt:
(I gave it a lot of thought and I think it is working, but do point out if it isn't or there is something fundamentally wrong)

What do you guys think of this attempt:
(I gave it a lot of thought and I think it is working, but do point out if it isn't or there is something fundamentally wrong)

added 64 characters in body
Source Link
cmhteixeira
  • 967
  • 12
  • 22
  • @tcooc's answer was quite cool. Didn't know about it before and will leverage it in the future.
  • I also enjoyed @MatthewRideout's answer, but it uses an external library!!

What do you guys think of this attempt:
(iI gave it a lot of thought and I think it is working, but do point out if it doesn'tisn't or there is something fundamentally wrong)

  • @tcooc's answer was quite cool. Didn't know about it before and will leverage it in the future.
  • I also enjoyed @MatthewRideout's answer, but it uses an external library!!

What do you guys think of this attempt:
(i think it is working, but do point out if it doesn't)

  • @tcooc's answer was quite cool. Didn't know about it and will leverage it in the future.
  • I also enjoyed @MatthewRideout's answer, but it uses an external library!!

What do you guys think of this attempt:
(I gave it a lot of thought and I think it is working, but do point out if it isn't or there is something fundamentally wrong)

Source Link
cmhteixeira
  • 967
  • 12
  • 22

  • @tcooc's answer was quite cool. Didn't know about it before and will leverage it in the future.
  • I also enjoyed @MatthewRideout's answer, but it uses an external library!!

Whenever possible, I give a shot at developing this kind of things on my own, rather than going for a library. You end up learning a lot of concepts which seemed daunting before.

What do you guys think of this attempt:
(i think it is working, but do point out if it doesn't)

 class Pool{
        constructor(maxAsync) {
            this.maxAsync = maxAsync;
            this.asyncOperationsQueue = [];
            this.currentAsyncOperations = 0
        }

        runAnother() {
            if (this.asyncOperationsQueue.length > 0 && this.currentAsyncOperations < this.maxAsync) {
                this.currentAsyncOperations += 1;
                this.asyncOperationsQueue.pop()()
                    .then(() => { this.currentAsyncOperations -= 1; this.runAnother() }, () => { this.currentAsyncOperations -= 1; this.runAnother() })
            }
        }

        add(f){  // the argument f is a function of signature () => Promise
            this.runAnother();
            return new Promise((resolve, reject) => {
                this.asyncOperationsQueue.push(
                    () => f().then(resolve).catch(reject)
                )
            })
        }
    }

//#######################################################
//                        TESTS
//#######################################################

function dbCall(id, timeout, fail) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (fail) {
               reject(`Error for id ${id}`);
            } else {
                resolve(id);
            }
        }, timeout)
    }
    )
}


const dbQuery1 = () => dbCall(1, 5000, false);
const dbQuery2 = () => dbCall(2, 5000, false);
const dbQuery3 = () => dbCall(3, 5000, false);
const dbQuery4 = () => dbCall(4, 5000, true);
const dbQuery5 = () => dbCall(5, 5000, false);


const cappedPool = new Pool(2);

const dbQuery1Res = cappedPool.add(dbQuery1).catch(i => i).then(i => console.log(`Resolved: ${i}`))
const dbQuery2Res = cappedPool.add(dbQuery2).catch(i => i).then(i => console.log(`Resolved: ${i}`))
const dbQuery3Res = cappedPool.add(dbQuery3).catch(i => i).then(i => console.log(`Resolved: ${i}`))
const dbQuery4Res = cappedPool.add(dbQuery4).catch(i => i).then(i => console.log(`Resolved: ${i}`))
const dbQuery5Res = cappedPool.add(dbQuery5).catch(i => i).then(i => console.log(`Resolved: ${i}`))

This approach provides a nice API, similar to thread pools in scala/java.
After creating one instance of the pool with const cappedPool = new Pool(2), you provide promises to it with simply cappedPool.add(() => myPromise).
Obliviously we must ensure that the promise does not start immediately and that is why we must "provide it lazily" with the help of the function.

Most importantly, notice that the result of the method add is a Promise which will be completed/resolved with the value of your original promise! This makes for a very intuitive use.

const resultPromise = cappedPool.add( () => dbCall(...))
resultPromise
.then( actualResult => {
   // Do something with the result form the DB
  }
)