简体   繁体   English

停止执行其他代码

[英]Stop further code from executing

I have a request: 我有个请求:

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

If any of there errors do happen I need to exit the whole parent function. 如果确实发生任何错误,我需要退出整个父函数。 I can't put a return in this request since it exits only this method. 我不能在此请求中返回任何内容,因为它仅退出此方法。 I thought there is a possibility to do a callback like: 我认为有可能进行如下回调:

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

But how to work with it? 但是如何使用它呢? It is inside an anonymous function, I don't know where to place its contents. 它在匿名函数内部,我不知道将其内容放置在何处。 I also tried to use try / catch but I can't throw errors to the outside handler because of Error: Unhandled "error" event. ([object Object]) 我也尝试使用try / catch但是由于Error: Unhandled "error" event. ([object Object])我无法向外部处理程序抛出错误Error: Unhandled "error" event. ([object Object]) Error: Unhandled "error" event. ([object Object]) , see code below: Error: Unhandled "error" event. ([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?
  }
});

But even if this worked I am not sure if this code will do what I need. 但是,即使这行得通,我不确定这段代码是否可以满足我的需求。 The request is asynchronous so what if the rest of the code gets triggered before then ? 该请求是异步等什么,如果代码的其余部分被触发之前then Is that even possible? 那有可能吗?

So I basically need to return 0; 所以我基本上需要return 0; the parent function somehow and if there are any errors I need to have a handler for them. 父函数以某种方式,如果有任何错误,我需要为他们提供一个处理程序。 Any ideas for this? 有什么想法吗?

You seem to be missing the concept. 您似乎错过了这个概念。 Firstly as already stated, all mongoose operations return a Promise or at least a "Promise like" object which can immediately be resolved via a then() instead of passing in a callback function. 首先,如前所述,所有猫鼬操作都返回Promise或至少一个“ Promise like”对象,可以立即通过then()解决该对象,而不用传递回调函数。 This can either present in two ways. 这可以两种方式出现。

Either with async/await syntax and a try..catch block: 使用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();
  }

})()

Or with standard then() and catch() syntax: 或使用标准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() );

})()

And the output of both listings is just the same: 两个清单的输出是相同的:

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)

As you can see the function happily returns it's value where the count remains 3 or under, but then throws an exception which stops further execution when the count would be greater than 3 since the "never get here" message never gets logged. 如您所见,函数会在count保持为3或3以下的情况下愉快地返回其值,但随后会抛出异常,当count大于3时,它将停止进一步执行,因为"never get here"消息从未被记录。

So there is no need for "callbacks" here and you would not use one unless you wrapped it in a Promise can did the same type of error handling anyway. 因此,这里不需要“回调”,除非您将其包装在Promise中,否则无论如何它都不会执行相同类型的错误处理。

But if you have an "error" then throw the error. 但是,如果您遇到“错误”,则throw错误。 This works fine in a promise chain, but a "callback" which does not return as a Promise is simply not part of that chain and can never be "caught". 这在promise链中可以正常工作,但是不会作为Promise返回的“回调”根本不是该链的一部分,也永远不会“被抓住”。 So simply don't use the callback when you don't need to. 因此,根本不需要使用回调。

Just for kicks, wrapping a callback with a Promise would be done like: 只是为了踢一下,用Promise包装一个回调就可以做到:

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

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

      resolve(count);
    })
  );
};

But it's noted not to be necessary considering the native methods return something you can resolve as a Promise anyway. 但是要注意的是,考虑到本机方法无论如何都会返回可以作为Promise解析的内容,因此没有必要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM