【问题标题】:NodeJS: promise worked insead of async/awaitNode JS:promise 代替了 async/await
【发布时间】:2019-12-12 04:34:02
【问题描述】:

我有种子文件

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();

这段代码的输出是

calling
resolved

我研究后写了这段代码

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();

输出正确

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

根据此声明,第一个代码应该可以工作 异步函数返回一个承诺。反之亦然。每个返回 promise 的函数都可以被认为是异步函数

我无法理解它缺少什么,我是 Nodejs 的新手 帮助将不胜感激

【问题讨论】:

  • 关于异步函数返回 promise 是正确的,但是第二个块起作用而第一个块不起作用的原因是 admin.save 方法具有回调函数。在第二个块中,promise 的结构是仅在执行回调时才解析 promise。第一个块将立即解决,因为不会等待回调。

标签: node.js promise async-await


【解决方案1】:

您没有为new_admin.save() 接口提供文档,但在99% 的情况下,当接口同时支持promise 和旧的回调样式时,如果您传递回调,那么它将不会返回promise。

所以,当你这样做时:

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

您将回调传递给admin.save(),因此它不会返回承诺。所以,await 没有任何用处。它不会等待异步操作完成。 await 仅当它等待的值是一个承诺时才会做一些有用的事情。

相反,不要混合使用普通的回调和承诺。完全使用 Promise。

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;
  }
}

或者,不使用 `await',您可以这样做:

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;        
    });
};

【讨论】:

  • Admin 似乎是猫鼬模型,所以是的,您描述的行为确实适用于它。
  • 感谢理解,我现在理解概念了。
猜你喜欢
  • 2020-02-05
  • 1970-01-01
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2019-06-12
  • 2017-06-13
  • 1970-01-01
相关资源
最近更新 更多