最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

arrays - Javascript - Pass anonymous functions to Promise.all - Stack Overflow

programmeradmin2浏览0评论

I'm trying to make multiple API calls concurrently using the Promise.all method with Axios, based on this example:

getUsers() { 
    return axios.get('/users');
}

getSessions() { 
    return axios.get('/sessions');
}

Promise.all([getUsers(), getSessions()])
    .then(results => {
      // Use the data
    })
    .catch(error => {
      // Catch the error
    });

However, as I will only know what concurrent API calls I need to make at this stage based on the result of a previous API call in the promise chain, I'm attempting to pass in an array of anonymous functions to the function in the form of:

var array = [];
array.push(() => {return axios.get('/users')}); 
array.push(() => {return axios.get('/sessions')});

Promise.all(array).then....

This doesn't work, and I understand that this is because I'm passing in function objects instead of referencing actual Promise objects as the method expects. However, pushing just axios.get(...) methods to the array results in them being called immediately, instead of later when the Promise.all method is executed.

I'm not sure how to do this properly, or whether there's a better approach to achieve what I'm after...

I'm trying to make multiple API calls concurrently using the Promise.all method with Axios, based on this example:

getUsers() { 
    return axios.get('/users');
}

getSessions() { 
    return axios.get('/sessions');
}

Promise.all([getUsers(), getSessions()])
    .then(results => {
      // Use the data
    })
    .catch(error => {
      // Catch the error
    });

However, as I will only know what concurrent API calls I need to make at this stage based on the result of a previous API call in the promise chain, I'm attempting to pass in an array of anonymous functions to the function in the form of:

var array = [];
array.push(() => {return axios.get('/users')}); 
array.push(() => {return axios.get('/sessions')});

Promise.all(array).then....

This doesn't work, and I understand that this is because I'm passing in function objects instead of referencing actual Promise objects as the method expects. However, pushing just axios.get(...) methods to the array results in them being called immediately, instead of later when the Promise.all method is executed.

I'm not sure how to do this properly, or whether there's a better approach to achieve what I'm after...

Share Improve this question asked Apr 8, 2018 at 18:22 user2521119user2521119 1653 silver badges14 bronze badges 3
  • 1 What do you mean by "results in them being called immediately, instead of later when the Promise.all method is executed."? In your example you are filling the array immediately before calling Promise.all anyway. You might want to post your actual code where you decide "what concurrent API calls I need to make at this stage based on the result of a previous API call in the promise chain". – Bergi Commented Apr 8, 2018 at 19:32
  • I agree with Bergi. Your question doesn't make much sense. The entire point of Promise.all is to wait for a collection of Promises to resolve. If you don't have those Promises yet then there is no point on using Promise.all for anything, and you don't have those Promises until axios.get(x) has been called, so it seems like calling those functions immediately is exactly what you want to do. – Paul Commented Apr 8, 2018 at 19:54
  • @Paulpro @Bergi sorry if it wasn't clear - by "results in them being called immediately, instead of later when the Promise.all method is executed.", what I meant was if I did something like array.push(axios.get('/users')) then the axios.get() method would be executed immediately as part of the push to the array, instead of being executed later when I invoked the Promise.all() method with the total array contents.. – user2521119 Commented Apr 10, 2018 at 22:06
Add a comment  | 

4 Answers 4

Reset to default 11

I am not familiar with Axios, but if I understand correctly axios.get returns a Promise, which you need for Promise.all. How about:

Promise.all(array.map(f => f()).then....

That way your functions are called when you actually want, and the map will give you an array of their results, so an array of Promises.

Note that this is essentially the same as the example you have cited with [getUsers(), getSessions()] – with the difference that your functions are anonymous and called implicitly using the map, instead of explicitly by their names. This way you have more flexibility in which functions actually get called.

Basically, in siplest scenario, to use anonymous function as a wrapper, you need to call it before you are put it to Promise.all.

So just try to :

const f = async () => {return service.myFunc();}

Promise.all([f()])

so, your wrapper (f) calling before, and you are providing array with one Promise.

or

Promise.all([(async () => {const result = await service.myFunc(); return result;})()]);

or (equal) :

const myPromise = (async () => {const result = await service.myFunc(); return result;})();

Promise.all([myPromise]);

So Promise will be provided to Promise.all, not just raw function. Also, be carefully and do not forget to use await in case of "big anonym function body".

i've been scratching my head about this for the longest time. in the first example you call the functions here:

Promise.all([getUsers(), getSessions()])

but in the second the anonymous functions are just stated, never called:

array.push( ()=>{return axios.get('/users')} );

so you would need to do this and call them as you pushed them:

array.push( (()=>{return axios.get('/users')}) () );

I also had this issue and found out that you can do it with p-all:

import pAll from 'p-all'

await pAll([() => { /* ... */ }, () => { /* ... */ }])
发布评论

评论列表(0)

  1. 暂无评论