简体   繁体   中英

Clearner way to wait for function to complete before continuing

First I fetch a random quote from a public api. Only AFTER I actually have a quote I want to render the page including that quote.

I am a JavaScript newbie so please bear with me if this is a stupid question.

I was struggling with waiting for the api call to return BEFORE continuing with rendering the page. I wanted to do the following, but this doesn't work because res.render will be called before I have a quote. (note: I am using Express and Axios)

async function getRandomQuote() {
    try {
        const res = await axios.get("https://api.quotable.io/random?tags=famous-quotes")
        console.log(`${res.data.content} - ${res.data.author}`)     //This prints fine
        return res.data
    } catch(e) {
        console.log('error', e)
    }
}

app.get('/', (req, res) => {

    const quote = getRandomQuote()
    console.log(`${quote.content} - ${quote.author}`)    //This prints 'undefined' because 'getRandomQuote' isn't finished yet

    res.render('home', { quote })
})

The only way I figured out to do it is as follows, but I find this really messy. Is there a cleaner way to do this? Or do I always need to put all the lines of code that I want to wait for each other in an async function?

async function getRandomQuote() {
    try {
        const res = await axios.get("https://api.quotable.io/random?tags=famous-quotes")
        console.log(`${res.data.content} - ${res.data.author}`)     //This prints fine
        return res.data
    } catch(e) {
        console.log('error', e)
    }
}

app.get('/', (req, res) => {

    const getQuoteAndRender = async() => {
        const quote = await getRandomQuote()
        console.log(`${quote.content} - ${quote.author}`)    //This prints only if I wrap everything in yet another aync function, otherwise it will not wait for 'getRandomQuote' to complete

        res.render('home', { quote })
    }
    getQuoteAndRender()
})

(Note: I realize rendering the page after I successfully get a quote is not ideal either because this means I will not get a page at all if the quote api (for some reason) doesn't work. But for now I just want to know how to do this with the waiting.)

Heres what you need to do. Make your controller async by doing this app.get('/', async (req, res)

app.get('/', async (req, res) => {

const quote = await getRandomQuote()
console.log(`${quote.content} - ${quote.author}`)    //This prints 'undefined' because 'getRandomQuote' isn't finished yet

res.render('home', { quote })
})

Try this:

getRandomQuote()
.then(quote => {
  console.log(`${quote.content} - ${quote.author}`) 
  res.render('home', { quote })
});

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