Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[NodeJS] Problema com Async/Await na ordem de execução das funções

Estou automatizando um projeto que pega os tweets de uma conta que é inputada pelo usuário ao executar o programa. Depois de pegar os tweets, o programa salva os tweets em um array e, em seguida, traduz os tweets.

Para isso, criei uma pasta ./robots onde estou colocando os arquivos input.js, twitter.js e translate.js, onde cada um é responsável pela sua função. No arquivo index.js eu faço a chamada de cada um dos arquivos e defino a ordem de execução. Logo, meus arquivos estão dessa forma:

Index.js

const robots = {
    input: require("./robots/input.js"),
    state: require("./robots/state.js"),
    twitter: require("./robots/twitter.js"),
    translate: require("./robots/translate.js"),
};

async function start() {
    robots.input();
    await robots.twitter();
    await robots.translate();
}

start();

Input.js

const readline = require("readline-sync");
const state = require("./state.js");

function robot() {
    const content = {
        tweets: [],
        translatedTweets: [],
    };

    content.userName = askAndReturnUserName();
    state.save(content);

    function askAndReturnUserName() {
        return readline.question(
            "Type the @ from the user that you want to analyze: ",
        );
    }
}

module.exports = robot;

Twitter.js

const Twitter = require("twitter");
const state = require("./state.js");

async function robot() {
    console.log("> [twitter-robot] Starting...");
    const content = state.load();
    await fetchTweetsFromUser(content);
    state.save(content);

    async function fetchTweetsFromUser(content) {
        const client = new Twitter({
            consumer_key: "xxxx",
            consumer_secret:
                "xxx",
            access_token_key:
                "yyy",
            access_token_secret:
                "yyy",
        });

        const params = {
            screen_name: content.userName,
            count: 30,
        };

        client.get("statuses/user_timeline", params, function(
            error,
            tweets,
            response,
        ) {
            console.log(
                "> [twitter-robot] I just found " +
                    Object.keys(tweets).length +
                    " tweets!",
            );
            tweets.forEach((tweet) => {
                content.tweets.push(tweet.text);
            });
        });
    }
}

module.exports = robot;

Translate.js

const translate = require("translate");
const state = require("./state.js");

async function robot() {
    console.log("> [translate-robot] Starting...");
    const content = state.load();
}

module.exports = robot;

O meu problema é que eu quero que o translate.js só entre em execução APÓS o twitter.js terminar rodar. Hoje o console imprime da seguinte forma:

> [twitter-robot] Starting...
> [translate-robot] Starting...
> [twitter-robot] I just found 30 tweets!

E o certo seria:

> [twitter-robot] Starting...
> [twitter-robot] I just found 30 tweets!
> [translate-robot] Starting...

Conseguem apontar onde está o meu erro?

1 resposta
solução!

Pelo que eu vi do seu código, precisa fazer alguns ajustes.

No seu arquivo Translate.js, você tem uma funçâo assíncrona chamada robot. Dentro dela, você não usou o await

No seu arquivo Twitter.js, você tem uma funçâo assíncrona chamada robot. Dentro dela, você usou o await para chamar a função "fetchTweetsFromUser".

Porem, dentro desta função "fetchTweetsFromUser" não tem await. A chamada para ""statuses/user_timeline"" retorna uma promisse. Precisaria refatorar esta chamada para trabalhar com await, acredito que isso resolveria o seu problema.