devCrow
devCrow

Reputation: 88

javascript async await I don't understand how it works

Hi I'm studying more deeply about Javascript async/await and I have some code that I don't understand.

In this code, I sent an array [1,2,3,4] to a function called timeCall at first and sent it with [5,6,7,8] again. So, the way I expect the code to work is

1 2 3 4
h e l l o
5 6 7 8
h e l l o

It's h e l l o, why

1 5
h e l l o
2 6
h e l l o 

I'm not sure if this is handled like this. If I use a map instead of a for of statement, after 1 to 8 are finished, hello comes out repeatedly. I think now, when I meet await, I move on to the micro task and send the 5 6 7 8 below. I'm thinking there's no such thing as a problem

1 2 3 4 h e l l o 5 6 7 8 ....

How do I modify the code to output data like this?

const timeArrs = [
  'h',
  'e',
  'l',
  'l',
  'o'
]

function time(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 3000);
  })
}

function timeArrProcessing(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 2000);
  })
}

function hi() {
  return Promise.all(timeArrs.map(async(arr) => {
    await timeArrProcessing(arr);
  }));
}

async function timeCall(arrs) {
  for(const arr of arrs) {
    await time(arr);
    await hi();
  }
  console.log('End');
}

timeCall([1, 2, 3, 4]);
timeCall([5, 6, 7, 8]);

Upvotes: 1

Views: 330

Answers (1)

Sully
Sully

Reputation: 405

As mentioned in the comments, there are a couple of problems in your code... Firstly, just calling an async function will immediately start it running 'in the background' and it won't block other code, so these lines are just kicking off two instances of timeCall that'll run at the same time

timeCall([1, 2, 3, 4]);
timeCall([5, 6, 7, 8]);

If you want the first one to complete before running the second, you need to await it. But since await only works in async functions, you'll probably want an async iife to run them

(async()=>{
  await timeCall([1, 2, 3, 4]);
  await timeCall([5, 6, 7, 8]);
})()

You've also added the hi function after every element is completed, not after they're all complete, so you probably want to change your timeCall to this:

async function timeCall(arr) {
  for(const elem of arr) {
    await time(elem);
  }
  await hi();
}

Also - it looks like you might want the hi to pause between letter in 'hello'? If so, you'll need something like this:

async function hi() {
  for(const elem of timeArrs) {
    await timeArrProcessing(elem);
  }
}

So, to put that all together, try the below to see if it works for you:

const timeArrs = [
  'h',
  'e',
  'l',
  'l',
  'o'
];

(async()=>{
  await timeCall([1, 2, 3, 4]);
  await timeCall([5, 6, 7, 8]);
  console.log('End');
})()

async function timeCall(arr) {
  for(const elem of arr) {
    await time(elem);
  }
  await hi();
}

function time(elem) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(elem));
    }, 3000);
  })
}

function timeArrProcessing(arr) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      res(console.log(arr));
    }, 2000);
  })
}

async function hi() {
  for(const elem of timeArrs) {
    await timeArrProcessing(elem);
  }
}

Upvotes: 0

Related Questions