Doubt when exporting Promise

Asked

Viewed 308 times

1

I have an async Function that does a get for an api and returns a random word:

word js.

require('dotenv').config();
const config = require('./config.js')
const axios = require('axios');
const axiosConfig = { 
    headers: { // speciyfy the headers
        'X-Mashape-Key': config.wdKey,
        "Accept": "application/json"
    }
}

module.exports = async function requestWord() {
  const response = await axios.get('https://wordsapiv1.p.mashape.com/words/?random=true', axiosConfig)
  return await response.data.word
}

Ai I want to use the return of this function, in case the word, as parameter in another function that makes the get in the google api.

image js.

require('dotenv').config();
const requestWord = require('./words.js')
const {google} = require('googleapis')
const config = require('./config.js')
const customSearch = google.customsearch('v1')

const f = requestWord

console.log(f())

async function searchImages(word){
    try{
    let URLs
    const URLsArray = await fetchAndReturnURLs(word)
    async function fetchAndReturnURLs(query){
        const response = await customSearch.cse.list({
            auth: config.ggApiKey,
            cx: config.ggCx,
            q: query,
            searchType: 'image',
            num: 2,
        })
        URLs = await response.data.items.map((item) => {
            return item.link
        })
    }
    return URLs
    }
    catch(err){
    }
}

this console.log(f()) returns Promise { <pending> }

  • This address you are trying to access is asking for the API key to authenticate your request: API Keys. In the headers you will have to add a line with the API key "X-RapidAPI-Key": {Chave-da-API}

3 answers

2

What’s going on

When you write a function async, the result is always a Promise. In this case, as you depend on a genuinely asynchronous function and you are not waiting through await or chained with .then, you are printing to Promise which is still pending (pending).

Even if Promise was solved, the result would still be an object Promise.

Simplified reproduction

A simpler / isolated way to reproduce what is happening:

async function foo() {
    return 42;
}

console.log(foo())

Although it contains nothing of asynchronous fact, foo() returns a promise so the result is:

Promise {
  42,
  domain:
   Domain {
     domain: null,
     _events: { error: [Function: debugDomainError] },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [] } }

(nodejs12)

Alternative with async

async function foo() {
    return 42;
}

async function main() {
   console.log(await foo())
}

main();

Upshot:

42

Alternative with chaining

async function foo() {
    return 42;
}

foo().then(console.log)

Upshot:

42

0

It’s just to see if I understand, that really this business of Promise makes me very confused:

1 - When I have an async Function, it is synonymous with a precedent that will return a resolve or an error, so when I use the keyword await, I’m talking to the function solve this promise and return a value of it that would be an equivalent of then()?

2- await means "wait to solve( succeed with ) that part of the code to execute the other"?

3- the bot is already working well just want to understand well what is happening here:

async function getRandomLinkInArray(){
    let word = await requestWord()
    let array = await searchImages(word)
    let random = Math.floor(Math.random()*10)
    let imageId = word.split(' ').join('_') + '.jpg'
    return {link: array[random], id: imageId}
}

in this case above I can receive the value by calling getRandomLinkInArray(), but let’s say I have an equivalent function:

requestWord.then((word)=>{
  searchImages.then((array)=>{
    let random = Math.floor(Math.random()*10)
    let imageId = word.split(' ').join('_') + '.jpg'
    return {link: array[random], id: imageId}
  })
})

how would I retrieve that result above without async await? Would I have to create a Promise that would encapsulate all that code? I know async Function kind of is a Promise but what confuses me is how they two match in the code.

0

You don’t need to use the await in the return, response already has the result of the call, that is, the Promise has been solved.

Edit: It is necessary to use async/await or then() in function call f(), because the return of the function f() is a precedent. Example:

async getResponse() {
  const responseFromF = await f();
}

// OU

f().then(result => ...) // result contém o a resposta da função f()

There is a very good article about async/await, I recommend reading: https://javascript.info/async-await

  • So brother I took there but keeps returning { <pending> }

  • I get it, have you tried a console.log() in Sponse? To see if something is coming. I’m not remembering well, but maybe when calling f() you would have to use the async/await also, but I’m not sure now.

  • I managed to solve I did a asynchronous function on the images.js and inside it called await f() ai worked cool, Rigadão

  • Show! Then it worked with the async/await in the function and in the right call? I will edit my answer up there, if it helped you, it gives as an answer to if someone needs :)

  • 1

    @leofalmeida, the answer helped solve the problem, but the explanation is wrong and can harm users trying to solve the same problem. Utilise àwait in the response will not make the code wait for another, response nor is it a Promise, await simply do nothing in that case. The reason why the user receives pending in the answer, it is because the return of every function async is a Promise.

  • It makes sense, but still there’s no reason to put one await in that Return, but I understood the point. I will edit the answer. Thanks!

Show 1 more comment

Browser other questions tagged

You are not signed in. Login or sign up in order to post.