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内部非奇异函数,所以我猜