javascript - 停止执行更多代码

标签 javascript node.js mongodb mongoose

我有一个请求:

  Character.count({'character.ownerid': msg.author.id}, function (err, count) {
    if (err) {
      throw err;
    }

    if (count > 3) {
      err.message = 'Too many characters';
      //create error explanation and throw it
      throw err;
    }
  })

如果确实发生任何错误,我需要退出整个父函数。我无法在此请求中添加返回值,因为它仅退出此方法。我认为有可能进行如下回调:

Character.count({'character.ownerid': msg.author.id}, function (err, count, stop) {

但是如何使用它呢?它位于匿名函数内,我不知道将其内容放在哪里。我还尝试使用 try/catch 但由于 Error: Unhandled "error"事件,我无法向外部处理程序抛出错误。 ([object Object]),参见下面的代码:

Character.count({'character.ownerid': msg.author.id}, function (err, count) {
  if (err) {
    throw err;
  }

  if (count > 3) {
    var err = {};
    err.message = 'Too many characters';
    throw err;
  }
}).then((count) => {
  console.log('all good we may continue');
  console.log(count);
}).catch((err) => {
  if (err != undefined && err.length > 0) {
    msg.reply(err.message);
    return 0; //exit parent function?
  }
});

但即使这有效,我也不确定这段代码是否能满足我的需要。该请求是异步的,那么如果其余代码在 then 之前触发怎么办?这可能吗?

所以我基本上需要以某种方式return 0;父函数,如果有任何错误,我需要有一个处理程序。有什么想法吗?

最佳答案

您似乎缺少这个概念。首先,如前所述,所有 mongoose 操作都会返回一个 Promise 或至少一个“类似 Promise”的对象,该对象可以通过 then() 立即解析,而不是传入回调函数。这可以通过两种方式呈现。

使用 async/await 语法和 try..catch block :

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost/test';

mongoose.set('debug', true);
mongoose.Promise = global.Promise;

const characterSchema = new Schema({
  name: String
});

const Character = mongoose.model('Character', characterSchema);

const log = data => console.log(JSON.stringify(data,undefined,2));

const doCount = async () => {
  let count = await Character.count();

  if (count > 3)
    throw new Error("too many charaters");

  return count;

};


(async function() {

  try {
    const conn = await mongoose.connect(uri);

    await Promise.all(Object.entries(conn.models).map(([k,m]) => m.remove()))

    await Character.insertMany(
      ["Huey","Duey","Louie"].map(name => ({ name }))
    );

    let count = await doCount();
    log({ count });

    await Character.create({ name: 'Donald' });

    let newCount = await doCount();
    console.log("never get here");


  } catch(e) {
    console.error(e)
  } finally {
    mongoose.disconnect();
  }

})()

或者使用标准 then()catch() 语法:

const { Schema } = mongoose = require('mongoose');

const uri = 'mongodb://localhost/test';

mongoose.set('debug', true);
mongoose.Promise = global.Promise;

const characterSchema = new Schema({
  name: String
});

const Character = mongoose.model('Character', characterSchema);

const log = data => console.log(JSON.stringify(data,undefined,2));

function doCount() {
  return Character.count()
    .then(count =>  {

      if (count > 3)
        throw new Error("too many charaters");

      return count;
    });

};


(function() {

  mongoose.connect(uri)
    .then(conn => Promise.all(
      Object.entries(conn.models).map(([k,m]) => m.remove())
    ))
    .then(() => Character.insertMany(
      ["Huey","Duey","Louie"].map(name => ({ name }))
    ))
    .then(() => doCount())
    .then(count => log({ count }))
    .then(() => Character.create({ name: 'Donald' }))
    .then(() => doCount())
    .then(() => console.log("never get here"))
    .catch(e => console.error(e))
    .then(() => mongoose.disconnect() );

})()

两个列表的输出是相同的:

Mongoose: characters.remove({}, {})
Mongoose: characters.insertMany([ { _id: 5b0f66ec5580010efc5d0602, name: 'Huey', __v: 0 }, { _id: 5b0f66ec5580010efc5d0603, name: 'Duey', __v: 0 }, { _id: 5b0f66ec5580010efc5d0604, name: 'Louie', __v: 0 } ], {})
Mongoose: characters.count({}, {})
{
  "count": 3
}
Mongoose: characters.insertOne({ _id: ObjectId("5b0f66ec5580010efc5d0605"), name: 'Donald', __v: 0 })
Mongoose: characters.count({}, {})
Error: too many charaters
    at doCount (/home/projects/characters/index.js:20:11)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

正如您所看到的,该函数很高兴地返回 count 保持在 3 或以下的值,但随后抛出异常,当 count 更大时停止进一步执行少于 3,因为“never get here” 消息永远不会被记录。

因此,这里不需要“回调”,并且除非将其包装在 Promise 中,否则您不会使用“回调”,无论如何都可以执行相同类型的错误处理。

但是如果你有一个“错误”,那么抛出错误。这在 promise 链中工作得很好,但是不作为 promise 返回的“回调”根本不是该链的一部分,并且永远不会被“捕获”。因此,当您不需要时,请不要使用回调。

只是为了好玩,用 Promise 包装回调会像这样完成:

function doCount() {
  return new Promise((resolve,reject) =>
    Character.count().exec((err,count) => {

      if (count > 3)
        reject(new Error("too many charaters"));

      resolve(count);
    })
  );
};

但值得注意的是,考虑到 native 方法返回的内容无论如何都可以作为 Promise 解析。

关于javascript - 停止执行更多代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50615681/

相关文章:

javascript - 如何在angularjs中将负数显示为正数

javascript - AngularJS 获取范围内的选定项

javascript - 字符序列到分层 JSON - d3.sunburst

MongoDB 和 RDF

javascript - 验证 : How to configure VueRouter to open link on a new tab?

javascript - 在unity中调用函数会导致unity崩溃

node.js - 解析服务器设置用户 ACL 并分配角色

javascript - NodeJS Web 服务器,在服务器启动时加载 html 文件时出现问题

node.js - Mongoose 保存文档成功但没有反射(reflect)在数据库中

mongodb - CMD dockerfile未执行