Reputation: 190
I'm trying to launch simultanuously many asynchrnous functions. Some of them make some http calls and I obviously don't want to make the same call multiple times. So, how can this be done using ES6 Promises and if not, what machanism would you recommend to deal with this kind of situations.
Example of the issue:
const func1 = () => async1();
const func2 = () => async2().then(async1);
return Promise.all([func1(), func2()]);
async1 and async2 are asynchronous functions returning Promises. The issue is how to deal with three situations :
The last situation is the only one I call deal with right now to prevent same calls from launching multiple times.
Upvotes: 0
Views: 242
Reputation: 171679
You can reuse a promise object any time so if you store a request promise the first time it gets called you can return the stored promise on subsequent calls and avoid making multiple requests to same resource
const async1 = (() => {
let promise;
return (arg) => {
console.log(arg, ' = ', promise ? 'Cached request' : 'New request');
promise = promise || new Promise((res) => setTimeout(res, 500));
return promise.then(()=>arg);
}
})()
Promise.all([async1(1),async1(2)]).then(res=>console.log(res))
Upvotes: 1
Reputation: 23695
If I understand it right you want to ensure async1
in your example will not be called twice.
The easy and (quite low)-level of achieving that is memoization.
Say with lodash's _.memoize()
it would be
const async1 = _.memoize(async1, () => 1)
// wrapping func1 and func2 is not actually required in this case
const func1 = _.memoize(() => async1());
const func2 = _.memoize(() => async2().then(async1));
return Promise.all([func1(), func2()]);
Beware since you are unable to transparently switch from memoized to _un_memoized implementations on fly.
[UPD] since memoization relies on arguments passed you may need to pass resolver
callback. Say in your case async1
may either got zero arguments or something coming from previous promise(when used in .then
). So arguments are different but since we know all arguments don't matter we can pass resolver that returns constant as a key(say, '1')
Upvotes: 0