-1
        if (element[0] === '@notify_1_2') {
          // @ts-ignore
          async function checkStorage() {
            const json = await AsyncStorage.getItem('@alarm')
            const response = JSON.parse(json!)

            let dayDifference: any
            if (json !== null) {
              dayDifference = daysDiff(response, Date.now())
            }

            if (dayDifference > 30 || dayDifference == null) {
              return { id: 1, priority: 1 }
            }
          }

          checkStorage().then((res) => {
                console.log('in function on top of push', arrayTracker)
                arrayTracker.push(res)
                console.log('in function bottom of push', arrayTracker)
              })
        } else {
          arrayTracker.push({ id: 0, priority: 0 })
        }
      }
    })

    console.log('array tracker:', arrayTracker)

Output:

array tracker outside function: []
in function on top of push []
in function bottom of push [{…}]

I want it so that the array tracker outside function: [] console log waits till all the async/await stuff are done with their checks.

Right now I push a value to array but it always seems empty but in the console log bottom of push it seems like the value gets passed - seems like some async/await order I couldn't get right

Output wanted:

in function on top of push []
in function bottom of push [{…}]
array tracker outside function: [{…}]. <------ with value and not empty

EDIT

  response.forEach(async (element: any) => {
    const formatJson = JSON.parse(element[1])

    if (formatJson !== null) {
      const dayDifference = daysDiff(formatJson.closedTimeStamp, Date.now())

      if (dayDifference > 7) {
        arrayTracker.push(formatJson)
      }
    } else {
      if (element[0] === '@notify_1_2') {
        // @ts-ignore
        async function checkStorage() {
          const json = await AsyncStorage.getItem('@alarm')
          const response = JSON.parse(json!)

          let dayDifference: any
          if (json !== null) {
            dayDifference = daysDiff(response, Date.now())
          }

          if (dayDifference > 7 || dayDifference == null) {
            return { id: 1, priority: 1 }
          }
        }

        arrayTracker.push(await checkStorage())
        console.log('array tracker below push:', arrayTracker)
      } else {
        arrayTracker.push({ id: 0, priority: 0 })
      }
    }
  })

  console.log('array tracker outside function:', arrayTracker)

Output:

array tracker outside function: []
array tracker below push: [{…}]

Output wanted:

array tracker below push: [{…}]
array tracker outside function: [{…}]
  • What's the context of this code? Is it inside another function? If so, make that one `async` and do `arrayTracker.push(await checkStorage())` instead. – Felix Kling May 26 '21 at 21:54
  • Or use `Promise.all` if you don't want to run each async function sequentially but want to wait for all of them to finish. – Dominik May 26 '21 at 21:58
  • Where are you awaiting? It seems like the function you are in is not async or you are not awaiting it. Specifically because you are doing `checkStorage().then` instead of `await checkStorage()`, even in an async function it will not wait before moving on. – Jason Goemaat May 26 '21 at 21:59
  • @JasonGoemaat I have edited the code to show you with the modifications - The output is the same – nikomannelig May 26 '21 at 22:08
  • @FelixKling Edited the code base with your suggestion - its giving me the same output – nikomannelig May 26 '21 at 22:11
  • Because you still have the same problem. `response.forEach` won't wait until the async functions "are done". You want `Promise.all(response.map(...)).then(() => console.log(...))` or `await Promise.all(response.map(...)); console.log(...);`. And depending on how `arrayTracker` is used there might also be a cleaner way to create that array than to push to it. Anyways, this might help with how to think about think about callbacks that mutate "outside" values: https://felix-kling.de/blog/2019/javascript-callbacks-misconceptions.html – Felix Kling May 26 '21 at 22:12
  • See this: https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop – Jason Goemaat May 26 '21 at 22:26
  • @FelixKling - really helpful and thanks for article – nikomannelig May 26 '21 at 22:28

1 Answers1

0

You are not awaiting your call to checkStorage():

checkStorage().then((res) => {
      console.log('in function on top of push', arrayTracker)
      arrayTracker.push(res)
      console.log('in function bottom of push', arrayTracker)
    })

When you call checkStorage(), it begins executing. Then the first statement it hits is this:

const json = await AsyncStorage.getItem('@alarm')

Now this is an async call that might take a while. Now your code resumes below your checkStorage() call and your function can complete. Later when checkStorage() completes, the code inside your then() will execute.

Instead you need to use await checkStorage(). This means the function it is in needs to be async as well, and you need to await it.

const res = await checkStorage();
console.log('in function on top of push', arrayTracker)
arrayTracker.push(res)
console.log('in function bottom of push', arrayTracker)
Jason Goemaat
  • 28,692
  • 15
  • 86
  • 113