node.jsasync-awaitrequest-promiseyandex-api

Why does return still execute before multiple await statements?


From my understanding, await makes the entire function wait until the statement it precedes finishes, right? I'm not sure why the below code prints this:

RES: [object Promise]
cn: 你好wurld!
mg: வணக்கம் wurld!
xh: Molo wurld!
FINAL: Url hello!

Here's my code:

const rp = require('request-promise')
const apiKey = //commented out for obvious reasons lol

const muddle = async(toTranslate)=>{
  let options = {
    method: 'GET',
    json: true,
    uri: `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${toTranslate}&lang=en-zh`
  }
  let response = await rp(options)
  let newText = response.text[0]
  console.log('cn: ' + newText)

  options.uri =`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${toTranslate}&lang=zh-ta`
  response = await rp(options)
  newText = response.text[0]
  console.log('mg: ' +newText)

  options.uri =`https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${toTranslate}&lang=ta-xh`
  response = await rp(options)
  newText = response.text[0]
  console.log('xh: ' +newText)

  options.uri = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${newText}&lang=xh-en`
  response = await rp(options)
  newText = response.text[0]
  console.log('FINAL: ' + newText)

  return response.text[0] //why does this fire before all the lines that include await before it?
}


let toLog = muddle('Hello wurld!')
console.log('RES: '+ toLog)

Shouldn't RES: [object Promise] be the line that prints last? Sorry for the massive wall of code, but it's pretty redundant for the most part. Each block is just a request to a translate API, which translates the translation returned from the request preceding it. Am I misunderstanding how await works? I want to return the final string that's been run through translate four times ('Url hello!)


Solution

  • It is normal that RES is not printed last, because you don't wait for the muddle function to finish before logging that.

    you have two options to fix that:

    use the then syntax:

    muddle('Hello wurld!').then(toLog => {
      console.log('RES: '+ toLog)
    })
    

    Wrap your call in an other async function:

    async function main() {
      const toLog = await muddle('Hello wurld!')
      console.log('RES: '+ toLog)
    }
    main();
    

    Be careful with the second one, though: You may end up with synchronous code. Easier to handle but likely inefficient