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 curtida

Tente alterar o twitter.js para ficar assim:

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

function robot() {
	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,
		};

		await 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);
			});
			
			state.save(content);
		});
	}
	
	console.log("> [twitter-robot] Starting...");
	const content = state.load();
	fetchTweetsFromUser(content);
}

module.exports = robot;
1 curtida

@Lucas_Camara,
Obrigado pela resposta.

Mas, infelizmente, fiz as alterações que você sugeriu e o problema continuou o mesmo. Tem alguma outra ideia do que pode ser?

Abraços,
Caio Tracera.