简体   繁体   中英

Promise { pending }, async, await in Javascript

I'm trying to understand why this code returns "Promise { pending }".

const reduceDirections = (str) => {
    str = str.replace(/northsouth|southnorth|eastwest|westeast/ig, '')

            if (str.search(/northsouth|southnorth|eastwest|westeast/ig) === -1) {
                str = str.replace(/south|north|west|east/gi, '$& ').replace(/(^\s+|\s+$)/,'')
                console.log(str)
                return str

            } else {
                reduceDirections(str)
            }  
}

async function start(arr) {
    str = arr.join('')
    let res = await reduceDirections(str)
    return Promise.resolve(res)
}

console.log(start(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]))

When I console.log(str) from the reduceDirections() function I can see I have the result I want. But when I (one line later) return str I instead have "Promise pending"

I'm sorry for not understanding Promises and async await. I have tried to read on mdn and watch videos but I don't see how I can transfer that they show to this problem. Thanks in advance for help!

Several issues:

1) There is nothing asynchronous happening in reduceDirections , nor does it return a promise, so it makes no sense to use await on it.

2) The recursive part of your function does not return the recursive result, so change:

 } else {
     reduceDirections(str)
 }  

to:

 } else {
     return reduceDirections(str)
 }  

Then at least you can hope to have a useful string as return value

3) If you really insist on using await on something that is returned synchronously, then you can keep it, but it is unnecessary to do

return Promise.resolve(res)

... since an async function always returns a promise anyway. So just do

return res;

4) you don't wait for that promise to resolve. So you should await it's resolved value and use console.log on that . Change:

console.log(start(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]))

to:

start(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]).then(console.log)

But again, using promises is useless here and only complicates the code. You don't get any advantage from it.

The code return "Promise { pending }" because you are not awaiting for the promise to fulfil,

Should be console.log(await start(["NORTH", "SOUTH", "SOUTH", "EAST", "WEST", "NORTH", "WEST"]))

Complementing: As @trincot mentioned, you didn't need to make start async, neither await for reduceDirections(). But as i said, the return of start() is a pending promise because you are not awaiting for it to fulfil.

As @Andreas commented, my solution would only work inside other async function, otherwise start() shoud be treated as a Promise start().then() , like @trincot did in his answer.

Get rid of the line return Promise.resolve(res) . async functions return a promise anyway.

The first line you see on the console (WEST) is coming from the console.log statement in the reduceDirections function.

The Promise{ pending } is what the second console.log shows because that's the return value from the start function.

The question about why the Promise is pending is actually slightly more interesting. It's because the function is async if you remove the async part you get a resolved promise, but using async magically wraps the returned value of the function in a promise, it's that promise which is pending and not the one created by calling Promise.resolve().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM