Last active
November 3, 2017 23:30
-
-
Save AlexanderTserkovniy/0c4c64ca1e9f9fcfcaa8d2c2b97b1d22 to your computer and use it in GitHub Desktop.
Limit promise requests.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Oleksandr Tserkovnyi on 11/3/17. | |
* [email protected] | |
*/ | |
const assert = require('assert'); | |
const requester = strToRequest => { | |
return new Promise((res, rej) => { | |
const plus = Math.random() * 2000; | |
setTimeout(() => { | |
res(`${strToRequest} with num: ${plus}`); | |
}, 1000 + plus); | |
}); | |
}; | |
const arr = [ | |
() => requester('request0'), | |
() => requester('request1'), | |
() => requester('request2'), | |
() => requester('request3'), | |
() => requester('request4'), | |
() => requester('request5'), | |
() => requester('request6'), | |
() => requester('request7'), | |
() => requester('request8'), | |
() => requester('request9'), | |
() => requester('request10'), | |
() => requester('request11'), | |
() => requester('request12'), | |
() => requester('request13'), | |
() => requester('request14'), | |
() => requester('request15'), | |
() => requester('request16'), | |
() => requester('request17'), | |
() => requester('request18'), | |
() => requester('request19'), | |
() => requester('request20'), | |
() => requester('request21'), | |
() => requester('request22'), | |
() => requester('request23'), | |
() => requester('request24'), | |
() => requester('request25'), | |
() => requester('request26'), | |
() => requester('request27'), | |
() => requester('request28'), | |
() => requester('request29'), | |
() => requester('request30'), | |
() => requester('request31'), | |
() => requester('request32'), | |
() => requester('request33'), | |
() => requester('request34'), | |
() => requester('request35'), | |
() => requester('request36'), | |
() => requester('request37'), | |
() => requester('request38'), | |
() => requester('request39'), | |
() => requester('request40'), | |
() => requester('request41'), | |
() => requester('request42'), | |
() => requester('request43'), | |
() => requester('request44'), | |
() => requester('request45'), | |
() => requester('request46'), | |
() => requester('request47'), | |
() => requester('request48'), | |
() => requester('request49'), | |
() => requester('request50') | |
]; | |
const isArraySparse = arr => [...arr].indexOf(undefined) > -1; | |
const scheduler = (req, index, results, currentRequests) => { | |
const promise = req(); | |
currentRequests.push(promise); | |
promise.then(data => { | |
results[index] = data; | |
currentRequests.splice(currentRequests.indexOf(promise), 1); | |
}); | |
return promise; | |
}; | |
const limitPromiseAll = (arr, limit) => { | |
const internalArr = arr.slice(0); | |
const results = []; | |
const currentRequests = []; | |
let lastIndex = 0; | |
// [START] JUST FOR TESTING PURPOSES | |
// If you want to test assertion, please uncomment | |
// setTimeout(() => { | |
// limit = 4; | |
// }, 3000); | |
const intr = setInterval(() => { | |
console.info('>>>> Current amount of requests are: ', currentRequests.length); | |
assert.ok( | |
currentRequests.length <= limit, | |
` | |
Amount of requests is bigger than expected. | |
Current: ${currentRequests.length} | |
Expected: ${limit} | |
` | |
); | |
currentRequests.length === 0 && clearInterval(intr); | |
}, 50); | |
// [END] JUST FOR TESTING PURPOSES | |
return new Promise((res, rej) => { | |
internalArr.splice(0, limit).forEach(function requester (request, i) { | |
lastIndex = i; | |
request && scheduler(request, lastIndex, results, currentRequests) | |
.then(_ => lastIndex += 1) | |
.then(_ => requester(internalArr.shift(), lastIndex, results, currentRequests)) | |
.then(_ => results.length === arr.length && isArraySparse(results) === false && res(results)) | |
.catch(err => rej(err)); | |
}); | |
}); | |
}; | |
limitPromiseAll(arr, 7) | |
.then((resCollection) => (console.log(resCollection), resCollection)) | |
.then((resCollection) => { | |
assert.ok(resCollection[37].match(/^request37/), 'Incorrect order 37'); | |
assert.ok(resCollection[22].match(/^request22/), 'Incorrect order 22'); | |
assert.ok(resCollection[13].match(/^request13/), 'Incorrect order 13'); | |
assert.ok(resCollection[2].match(/^request2/), 'Incorrect order 2'); | |
assert.equal(resCollection.length, arr.length, 'Incorrect result length'); | |
assert.equal(isArraySparse(resCollection), false, 'NOT all results are with data'); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment