Vishal G
Vishal G

Reputation: 1541

NodeJS: promise worked insead of async/await

I have seed file

require('dotenv').config()

const db = require('./db');
const logger = require('./logger.js')
require('../models/adminModel')
var Admin = require('mongoose').model('Admins');

const seedAdmin = async () => {
  const new_admin = new Admin({email: "xyx@xyz.com", password: "admin@123"});
  await new_admin.save(function(err, task) {
    if (err)
      logger.error(`ERROR: ${err}`)
    logger.success(`Admin user created sucessfully with email: ${new_admin.email}`)
  });

  return 'resolved'
}

async function asyncCall() {
  console.log('calling');
  var result = await seedAdmin();
  console.log(result);
  process.exit();
}

asyncCall();

output of this code is

calling
resolved

I have written this code after researching

require('dotenv').config()

const db = require('./db');
const logger = require('./logger.js')
require('../models/adminModel')
var Admin = require('mongoose').model('Admins');


function seedAdmin() {
  return new Promise(resolve => {
    const new_admin = new Admin({email: "xyx@xyz.com", password: "admin@123"});
    new_admin.save(function(err, result) {
      if (err)
        logger.error(`ERROR: ${err}`)
        resolve('resolved');
      logger.success(`Admin user created sucessfully with email: ${new_admin.email}`)
      resolve('resolved');
    });
  });
}

async function asyncCall() {
  console.log('calling');
  var result = await seedAdmin();
  console.log(result);
  process.exit();
}

asyncCall();

outpute is correct

calling
✔  success   Admin user created sucessfully with email: xyx@xyz.com
resolved

According to this statment first code should work Async function returns a promise. The converse is also true. Every function that returns a promise can be considered as async function

I am not able to understand what is missing it it, I am new to Nodejs Help will be appreciated

Upvotes: 0

Views: 50

Answers (1)

jfriend00
jfriend00

Reputation: 708036

You don't provide the doc for the new_admin.save() interface, but in 99% of the cases when an interface supports both promises and the older callback style, if you pass a callback, then it will NOT return a promise.

So, when you do this:

  await new_admin.save(function(err, task) {
    if (err)
      logger.error(`ERROR: ${err}`)
    logger.success(`Admin user created sucessfully with email: ${new_admin.email}`)
  });

You're passing a callback to admin.save() and thus it does NOT return a promise. So, the await does nothing useful. It doesn't wait for that async operation to be done. await only does something useful if the value it is awaiting is a promise.

Instead, don't mix plain callbacks and promises. Use the promise entirely.

const seedAdmin = async () => {
  const new_admin = new Admin({email: "xyx@xyz.com", password: "admin@123"});
  try {
      let result = await new_admin.save();
      logger.success(`Admin user created sucessfully with email: ${new_admin.email}`)
      return 'resolved';
  } catch(err) {
      // log and rethrow so caller still sees error
      logger.error(`ERROR: ${err}`)
      throw err;
  }
}

Or, without using `await', you can just do this:

const seedAdmin = () => {
    const new_admin = new Admin({email: "xyx@xyz.com", password: "admin@123"});
    return new_admin.save().then(result => {
      logger.success(`Admin user created sucessfully with email: ${new_admin.email}`)
      return 'resolved';
    }).catch(err => {
       // log and rethrow so caller still sees error
       logger.error(`ERROR: ${err}`)
       throw err;        
    });
};

Upvotes: 3

Related Questions