Javascript 停止执行进一步的代码

Javascript 停止执行进一步的代码,javascript,node.js,mongodb,mongoose,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 thro

我有一个要求:

  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”事件,我无法向外部处理程序抛出错误。([对象])
,请参见下面的代码:

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?
  }
});
但即使这样做有效,我也不确定这段代码是否能满足我的需要。请求是异步的,因此如果在
之前触发其余代码,那么会怎么样?这可能吗


所以我基本上需要
返回0父函数,如果有任何错误,我需要为它们设置一个处理程序。有什么想法吗

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

使用
async/await
语法和
try..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));

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)

但是值得注意的是,考虑到本机方法返回的东西无论如何都可以作为承诺来解决,因此没有必要这样做。

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

使用
async/await
语法和
try..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));

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)

但值得注意的是,考虑到本机方法返回的内容无论如何都可以解析为承诺,因此没有必要这样做。

本机返回“承诺”。它内部不需要回调。只需
Character.count().then(…
并执行
if(count…
then()
中的内容)。文档可能更清晰,但它确实说
返回
,并且
查询
对象实际上是
然后()
。或者执行
Character.count().exec().then(…).catch(…)
作为“完整的”返回承诺。@Neil Lunn官方文档声明:
Mongoose查询不是承诺。它们有一个用于co和async/await的.then()函数,以方便使用。如果需要完整的承诺,请使用.exec()函数。
。老实说,我不确定这意味着什么,但这似乎不是一个完整的工作承诺。其次,我仍然不知道如何在出现错误时退出父函数。Catch在这里不起作用,请将所有内容都放在
中,然后
?出于某种原因,它似乎不正确,是吗?我知道,因为我链接了它。您可能没有请阅读完整的评论,因为我在初次提交后对其进行了编辑。您实际上并不“需要”exec()
,而且它是可选的。我知道,因为我一直都这样做,这正是
let count=wait Character.count()的原因
也适用于
async/await
语法。@Neil Lunn是的,我没有看到更新。好吧,我仍然有一个问题,即使是
exec
我也不能
抛出
错误来处理catch,而且
会返回
内部
catch
甚至退出父函数吗?我感觉不会,因为它在a内部非对称函数。所以我想你建议的唯一解决方案是将以下所有代码放入
,然后
,对吗?我想澄清一下这是什么。这段代码是一个更大的脚本的一部分。它只是检查是否有剩余空间供用户创建新字符。如果没有剩余空间,则退出,如果还有一些空间,则退出继续使用脚本。这就是为什么我希望它实际退出父函数,而不是移动
然后
中的所有其他代码,这将使代码更干净。以本机方式返回“承诺”。不需要在其内部回调。只需
Character.count()。然后(…
并执行
如果(将..
计数在
then()
中。文档可能更清晰,但它确实说
返回
,而
查询
对象实际上是一个
then()
。或者将
字符.count().exec().then(…).catch(…)
作为一个“完整”来执行返回承诺。@Neil Lunn官方文档声明:
Mongoose查询不是承诺。它们有一个用于co和async/await的.then()函数,以方便使用。如果需要完整的承诺,请使用.exec()函数。
。老实说,我不确定这意味着什么,但这似乎不是一个完整的工作承诺。其次,我仍然不知道如何在出现错误时退出父函数。Catch在这里不起作用,请将所有内容都放在
中,然后
?出于某种原因,它似乎不正确,是吗?我知道,因为我链接了它。您可能没有请阅读完整的评论,因为我在初次提交后对其进行了编辑。您实际上并不“需要”exec()
,而且它是可选的。我知道,因为我一直都这样做,这正是
let count=wait Character.count()的原因
也适用于
async/await
语法。@Neil Lunn是的,我没有看到更新。好吧,我仍然有一个问题,即使是
exec
我也不能
抛出
错误来处理catch,而且
会返回
内部
catch
甚至退出父函数吗?我感觉不会,因为它在a内部非奇异函数,所以我猜