Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

vuejs2 - Vue js, async inside foreach loop

created () {
    this.test();
},

test : function () {
        axios.get('/api/1', {
            headers : {
                'Access-Control-Allow-Origin' : '*',
                'session' : window.session_id
            }
        }).then((response) => {

            for (const item of response.data) {
                axios.get('/api/2', {
                    headers : {
                        'Access-Control-Allow-Origin' : '*',
                        'session' : window.session_id
                    }
                }).then((response) => {
                    item.subscribers = response.data.filter(o => { return o.status > 0 }).length;
                });
            };

            this.list = response.data;

        }).catch((error) => {
            console.log(error)
        })
    },

<tr v-for="val in list">
    @{{ val.subscribers }}
</tr>

here i am not getting 'subscribers' in the template as it is loading after rendering or i m not sure. how can i use async/await to load all data then render to the view

TIA

question from:https://stackoverflow.com/questions/65641235/vue-js-async-inside-foreach-loop

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem is here

            for (const item of response.data) {
                axios.get('/api/2', {
                    headers : {
                        'Access-Control-Allow-Origin' : '*',
                        'session' : window.session_id
                    }
                }).then((response) => {
                   // This finishes later than
                   // this.list = response.data occurs
                    item.subscribers = response.data.filter(o => { return o.status > 0 }).length;
                });
            };

            this.list = response.data;

You assign this.list which triggers Vue to re-render. Only later you assign subscribers to each individual item which Vue cannot detect. There are plenty of ways how to properly wait for the response. Because you are basically need everything to resolve in a synchronous way, I'd suggest to use async/await syntax for readability. I haven't tested the code, there might be a typo. But it gives you an idea I hope.


async function test() {
  try {
    const response = await axios.get('/api/1', {
      headers: {
        'Access-Control-Allow-Origin': '*',
        session: window.session_id,
      },
    });

    await Promise.all(response.data.map(async (item) => {
      const subscribers = await axios.get('/api/2', {
        headers: {
          'Access-Control-Allow-Origin': '*',
          session: window.session_id,
        },
      });
      item.subscribers = subscribers.filter((o) => o.status > 0).length;
    }));

    this.list = response.data;
  } catch (error) {
    console.log(error);
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...