HM.Park
HM.Park

Reputation: 829

how to execute the function after receiving the response value by executing two asynchronous functions at the same time

export default {
  data: () =>({
    data1: [],
    data2: [],
    lastData: []
  }),
  mounted() {
    asynchronous1(val, (data)=>{
      return this.data1 = data
    })
    asynchronous2(val, (data)=>{
      return this.data2 = data
    })
    function lastFuction() {
      this.lastData = this.data1.concat(this.data2)
    }
  },
}

After executing asynchronous1 and asynchronous2 at the same time, I want to execute lastFuction after receiving both response values.

Upvotes: 0

Views: 57

Answers (2)

Jaromanda X
Jaromanda X

Reputation: 1

Assuming asynchronous1 and asynchronous2 don't return Promises - which is likely the case since they take a callback function

You could do this (messy)

export default {
  data: () =>({
    data1: [],
    data2: [],
    lastData: []
  }),
  mounted() {
    let lastFunction = (() => {
      let count = 0;
      return () => {
        count++;
        if (count === 2) {
          this.lastData = this.data1.concat(this.data2);
        }
      };
    })();
    asynchronous1(val, (data) => {
        this.data1 = data;
        lastFunction();
    })
    asynchronous2(val, (data) => {
        this.data2 = data;
        lastFunction();
    })
  },
}

But it'll work

The nicer solution would be to use async/await and Promises

export default {
  data: () =>({
    data1: [],
    data2: [],
    lastData: []
  }),
  async mounted() {
    const p1 = new Promise(resolve => {
        asynchronous1(val, (data) => {
            this.data1 = data;
            resolve();
        })
    });
    const p2 = new Promise(resolve => {
        asynchronous2(val, (data) => {
            this.data2 = data;
            resolve();
        })
    });
    await Promise.all([p1, p2]);
    this.lastData = this.data1.concat(this.data2);
  },
}

I'd probably go as far as this though:

export default {
  data: () =>({
    data1: [],
    data2: [],
    lastData: []
  }),
  async mounted() {
    const promisify = fn => (...args) => new Promise(resolve => fn(...args, resolve));
    
    const p1 = promisify(asynchronous1);
    const p2 = promisify(asynchronous2);
    const [r1, r2] = await Promise.all([p1(val), p2(val)]);
    this.data1 = r1;
    this.data2 = r2;
    this.lastData = [...r1, ...r2];
  },
}

The difference here is that this.data1/this.data2 won't get populated until both asynchronous functions complete - which may not be to your liking

You could do

        const [r1, r2] = await Promise.all([
            p1(val).then(r => this.data1 = r), 
            p2(val).then(r => this.data2 = r)
        ]);

instead of

    const [r1, r2] = await Promise.all([p1(val), p2(val)]);
    this.data1 = r1;
    this.data2 = r2;

Which would get it to populate in the same way as your original code seems to want to do - I just hate using async/await AND .then ... but there are edge cases where it's a better option than pure async/await - in my opinion

Of course, if asynchronous1/2 can return a promise if you don't specify a callback function (getting more common these days) then the code may be even simpler

i.e

    const [r1, r2] = await Promise.all([asynchronous1(val), asynchronous2(val)]);

instead of

    const p1 = promisify(asynchronous1);
    const p2 = promisify(asynchronous2);
    const [r1, r2] = await Promise.all([p1(val), p2(val)]);

Upvotes: 1

Bezpalko Oleh
Bezpalko Oleh

Reputation: 127

You can have something like this:

async function func1() { ... }
async function func2() { ... }
async function func3() { ... }

async function main() {
  await Promise.all([func1, func2]);
  await func3();
}

Upvotes: 0

Related Questions