2

I am writing some code to simulate a Database call that I only want to make once, and store the result in a map (to prevent repeated round trips).

My code seems to work fine, but I am getting an unexpected result: when I remove one of the await values (highlighted below), the code appears to wait on the resolution of the promise (in that the console.log still waits for 5 seconds), but the logged value is still a Promise.

In my mind, this seems inconsistent, so I think my understanding of Promises might be lacking.

const inputs = ['a', 'b'];

let promiseOrValue

async function processor(input){
    if (promiseOrValue){
        await promiseOrValue
    }
    else {
        promiseOrValue = asyncFunction()
        await promiseOrValue
    }
    console.log(`${input} ${**await** promiseOrValue}`)
}

async function asyncFunction(){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('resolving')
            resolve('foo')
        }, 1000)
    })
}

inputs.forEach(processor)

I expect that either the console.log will print immediately with [object Promise], or it will wait 5 seconds and print foo. In fact, it waits 5 seconds, and then prints [object Promise].

nick zoum
  • 7,216
  • 7
  • 36
  • 80
  • 1
    Higher in that function you're doing `await promiseOrValue` anyway, so that's why you're waiting in either case. – hugo Aug 08 '19 at 10:14
  • A Promise object just promises that you will get a value at some point in the future. If you aren't going to *wait* for that value, then of course you'll get the promise and not the value. – Quentin Aug 08 '19 at 10:16
  • `.forEach()` does NOT pause for `await` inside its callback. So your `.forEach()` loop runs immediatley to completion which does not seem likely it's what you want. This code looks generally confused. You'd probably get better help with a good design if you backed up and described a little more exactly what you're trying to accomplish. Are you just trying to build a database cache for recently retrieved values so you can fetch a value from the cache if it's been recently retrieved? – jfriend00 Aug 08 '19 at 10:17

1 Answers1

1

The problem is you have awaited for promiseOrValue but don't assign its return data to any variable. So the process will be paused until promiseOrValue done.

await promiseOrValue;

You need to remove await to not pause your process.

Tien Duong
  • 2,517
  • 1
  • 10
  • 27
  • Thanks Tien. I think my assumption was that `await` mutated the value that is passed to it, but that must not be the case. – Richard Coates Aug 08 '19 at 10:17
  • 1
    @RichardCoates - No, `await` pauses the execution of that function until the promise you await resolves. The first `await` inside an `async` function causes that `async` function to pause and also immediately return a promise that will eventually be resolved when the function returns its final value. – jfriend00 Aug 08 '19 at 10:19
  • @jfriend00 - I understand that, what confuses me is that promiseOrValue is assigned a promise, which we've then awaited, but when we log it, it's still a promise, not a value. – Richard Coates Aug 08 '19 at 10:21
  • 1
    @RichardCoates - `promiseOrValue` never changes it's own value because of `await`. It's a promise. That's what it is. If you want the value out of it, you do `let value = await somePromise`. I'd suggest reading a few introductory tutorials on the use of `await`. You are missing a fundamental core concept for how it works with promises. – jfriend00 Aug 08 '19 at 10:22