I have multiple places where I need to make ajax requests to fetch the items corresponding to some ids. However, I only want to make a single request by accumulating these ids and debouncing the actual method that makes the ajax request...So far I've come up with this code, but it just feels ugly/non-reusable.
Is there any simpler/recommended method to achieve similar results without sharing resolve/promise variables like I did here?
Here's a fiddle
const fakeData = [{
id: 1,
name: 'foo'
},
{
id: 2,
name: 'bar'
},
{
id: 3,
name: 'baz'
}
];
let idsToFetch = [];
let getItemsPromise, resolve, reject;
const fetchItems = _.debounce(() => {
console.log('fetching items...');
const currentResolve = resolve;
const currentReject = reject;
// simulating ajax request
setTimeout(function() {
const result = idsToFetch.map((id) => fakeData.find(item => item.id == id));
currentResolve(result);
}, 400);
getItemsPromise = resolve = reject = null;
}, 500);
function getItems(ids) {
idsToFetch = ids.filter((id) => !idsToFetch.includes(id)).concat(idsToFetch);
if (!getItemsPromise) {
getItemsPromise = new Promise((_resolve, _reject) => {
resolve = _resolve;
reject = _reject;
});
}
fetchItems();
return getItemsPromise
.then((res) => {
return res.filter((item) => ids.includes(item.id));
})
}
setTimeout(() => {
console.log('first request start');
getItems([1]).then(res => console.log('first result:', res));
}, 100);
setTimeout(() => {
console.log('second request start');
getItems([1, 2]).then(res => console.log('second result:', res));
}, 200)
setTimeout(() => {
console.log('third request start');
getItems([1, 3]).then(res => console.log('third result:', res));
}, 300)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
setTimeout
that simulates the ajax request, then yeah it's pretty similar. \$\endgroup\$fakeData
was test data similar to what would be passed in, I just wanted to make sure that the rest of the code was actual code. please feel free to add more context to what you are accomplishing with your code. \$\endgroup\$