Skip to content

Instantly share code, notes, and snippets.

@AlexanderTserkovniy
Last active November 3, 2017 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AlexanderTserkovniy/0c4c64ca1e9f9fcfcaa8d2c2b97b1d22 to your computer and use it in GitHub Desktop.
Save AlexanderTserkovniy/0c4c64ca1e9f9fcfcaa8d2c2b97b1d22 to your computer and use it in GitHub Desktop.
Limit promise requests.
/**
* Created by Oleksandr Tserkovnyi on 11/3/17.
* kemperomg@gmail.com
*/
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