Node async await not waiting - node.js

When I run the below code and remove the setTimeout all the methods run asynchronously even with the await. Any ideas why the await does not wait.
const dotenv = require("dotenv");
dotenv.config({ path: "./config/.env" });
const { setTimeout } = require("timers/promises");
const module1 = require("./utils/module1");
const module2 = require("./utils/module2");
const module3 = require("./utils/module3");
const run = async () => {
await module1.import();
await setTimeout(60000);
await module2.import();
await setTimeout(120000);
await module3.import();
};
run();
Example of a module:
exports.import = async () => {
//do something
}

As #robertklep stated in the comments the problem is inside the actual method of the module.
Nothing was properly awaited inside the first method causing the second method to kick off.
Specifically I was incorrectly using readline and had to change the code as follows:
instead of
rl.on()
use
for await (const line of rl) { }

Related

nodejs async module exports

I am exporting a config js object asynchronously. How can I use the exported object in another module asynchronously?
module.export = (async function(){
connConf = await getDbConnectionConfiguration('administration_db');
const config = {
development: {
username: connConf.user,
password: connConf.password,
host: connConf.host,
database: connConf.database}
};
return config;
})();
Then I am importing the above module in another object as below,
const configs = await require('../config');
But I am getting the error message saying Unexpected reserved word 'await'
You have a typo in your config module: module.export should be module.exports.
Also, you are immediately calling your function on export and returning a pending Promise. It is better to remove last parenthesis and return the function itself:
//fixed typo V
module.exports = (async function(){
connConf = await getDbConnectionConfiguration('administration_db');
const config = {
development: {
username: connConf.user,
password: connConf.password,
host: connConf.host,
database: connConf.database
}
};
return config;
}); // <-- parenthesis removed here
Unexpected reserved word 'await' means that you are using await outside async function ("top-level awaits") and it can't be done in CommonJS (.js) modules.
One workaround is to wrap your code in an async function and call it:
const configsModule = require('./config'); // <-- your imported async function
async function init() {
const configs = await configsModule();
// all you code should be here now
console.log(configs);
}
// call init
init();
Another way is to use top-level awaits if your Node is version 14 or above and you switch to ES modules (.mjs):
// app.mjs
import configsModule from '../config';
const configs = await configsModule();

Node async await code writing style which one is good and optimized

I used to write code for async-await in (Style 1), other dev suggested me to write in (Style 2).
Can someone please explain to me what is the difference between both styles, for me it seems the same.
Code Style 1:
const fixtures = await fixtureModel.fetchAll();
const team = await teamModel.fetch(teamId);
Code Style 2:
const fixturesPromise = fixtureModel.fetchAll();
const teamPromise = teamModel.fetch(teamId);
const fixtures = await fixturesPromise;
const team = await teamPromise;
They are not the same.
The first will initialize a Promise, wait for it to complete, then initialize another Promise, and wait for the second Promise to complete.
The second will initialize both Promises at once and wait for both to complete. So, it will take less time. Here's a similar example:
// Takes twice as long as the other:
const makeProm = () => new Promise(resolve => setTimeout(resolve, 1000));
console.log('start');
(async () => {
const foo = await makeProm();
const bar = await makeProm();
console.log('done');
})();
// Takes half as long as the other:
const makeProm = () => new Promise(resolve => setTimeout(resolve, 1000));
console.log('start');
(async () => {
const fooProm = makeProm();
const barProm = makeProm();
const foo = await fooProm;
const bar = await barProm;
console.log('done');
})();
But you might consider making the code even clearer with Promise.all instead:
const [fixtures, team] = await Promise.all([
fixtureModel.fetchAll(),
teamModel.fetch(teamId)
]);

'Await' doesn't work with imported Async Function (email-deep-validator)

I'm trying to use the 'email-deep-validator' npm package ( https://www.npmjs.com/package/email-deep-validator ) following the examples:
const EmailValidator = require('email-deep-validator');
const emailValidator = new EmailValidator();
const { wellFormed, validDomain, validMailbox } = await emailValidator.verify('myEmail#myDomain.com');
But Node returns this error: SyntaxError: await is only valid in async function
I've checked in the code of this package that the verify function is defined like Async ( https://github.com/getconversio/email-deep-validator/blob/master/lib/index.js ) and I tried to execute the code with serveral versions of Node (9.2.0, 10.16.1, 12.7.0).
I'd appreciate an orientation. Thanks.
You can use await only in async function, the error message is pretty clear.
Example:
const EmailValidator = require('email-deep-validator');
const emailValidator = new EmailValidator();
async function main() {
const { wellFormed, validDomain, validMailbox } = await emailValidator.verify('myEmail#myDomain.com');
// ...rest of your code
}
main()
Thank at all for your help. This and other answers works properly:
#Rashomon:
You can use await only in async function, the error message is pretty clear.
Example:
const EmailValidator = require('email-deep-validator');
const emailValidator = new EmailValidator();
async function main() {
const { wellFormed, validDomain, validMailbox } = await emailValidator.verify('myEmail#myDomain.com');
// ...rest of your code
}
main()
You can only use await inside async functions.
const EmailValidator = require('email-deep-validator');
const emailValidator = new EmailValidator();
// top level async function
(async () => {
const { wellFormed, validDomain, validMailbox } = await emailValidator.verify('myEmail#myDomain.com');
})()

Jest functions export

I'm using jest+puppeteer and I have a code that I'd like to reuse across my project.
I use the following instruction:
https://jestjs.io/docs/en/getting-started
//adminLogin2.js
const admLog = function admLog () {
return
page.goto(data.config.env.host);
page.waitForSelector(data.selectors.admin.auth.input_login);
page.click(data.selectors.admin.auth.input_login);
page.type(data.selectors.admin.auth.input_login, data.credentials.business_email.login);
page.click(data.selectors.admin.auth.form_button_first);
// second step
page.waitForSelector(data.selectors.admin.auth.input_login_password);
page.click(data.selectors.admin.auth.input_login_password);
page.type(data.selectors.admin.auth.input_login_password, data.credentials.business_email.password);
page.click(data.selectors.admin.auth.form_button_second);
page.waitForSelector(data.selectors.admin.auth.business_login_button);
page.click(data.selectors.admin.auth.business_login_button);
page.waitForSelector(data.selectors.admin.auth.business_body);
}
module.exports = admLog;
//test
const data = require('../config');
const admLog = require('../struct/Login/adminLogin2');
describe('GetPackage :: Auth', () => {
it('Admin Email', async () => {
await admLog();
});
});
Test could be run without exceptions, but nothing happens, in headless:false mode Chrome is just run and closed.
What should be fixed?
Add the async/await in the admLog function.
Remove the return statement to prevent the Automatic semicolon insertion
So the final adminLogin2.js file should be like this:
//adminLogin2.js
const admLog = async function() {
await page.goto(data.config.env.host);
await page.waitForSelector(data.selectors.admin.auth.input_login);
await page.click(data.selectors.admin.auth.input_login);
await page.type(data.selectors.admin.auth.input_login, data.credentials.business_email.login);
await page.click(data.selectors.admin.auth.form_button_first);
// second step
await page.waitForSelector(data.selectors.admin.auth.input_login_password);
await page.click(data.selectors.admin.auth.input_login_password);
await page.type(data.selectors.admin.auth.input_login_password, data.credentials.business_email.password);
await page.click(data.selectors.admin.auth.form_button_second);
await page.waitForSelector(data.selectors.admin.auth.business_login_button);
await page.click(data.selectors.admin.auth.business_login_button);
await page.waitForSelector(data.selectors.admin.auth.business_body);
}
module.exports = admLog;

nodejs How to fix `browser.newPage is not a function` using puppeteer-core?

I am trying to use pupetteer-core but when I run my code.
const puppeteer = require('puppeteer-core');
module.exports= run = () => {
const url = 'https://example.com'
const browser = puppeteer.launch();
const page = browser.newPage().then(function(page){
page.goto(url)
return browser
};
run().catch(console.error.bind(console))
I get this error
TypeError: browser.newPage is not a function
The problem in your code is that puppeteer works with Promises, meaning that most functions will return a Promise instead of the value directly. This means that you ether have to use then function or await statements to get the value.
Code sample
module.exports = run = async () => {
const url = 'https://example.com';
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto(url);
return browser;
};
Note that the function is marked as async now, making it implicitly returning a Promise. That means to wait for the run() function to finish, you would have to call it from within another async function like this:
(async () => {
const browser = await run();
})();

Resources