多个嵌套的猫鼬承诺的结构
Structure of multiple nested Mongoose promises
我如何构造一个函数,其中有多个 Mongoose.findOne()
相互嵌套?
我需要做类似的事情
const userId = '...';
const postId = '...';
const imageId = '...';
User.findById(userId).then(user => {
if (!user) {
return res.status(400).json({
status: 'error',
err: 'User not found',
});
}
Post.findById(postId).then(post => {
if (!post) {
return res.status(400).json({
status: 'error',
err: 'Post not found',
});
}
Image.findById(imageId).then(image => {
if (!image) {
return res.status(400).json({
status: 'error',
err: 'Image not found',
});
// DO SOMETHING WITH VARIABLES 'user', 'post', AND 'image'
}).catch(err => { .. });
}).catch(err => { .. });
}).catch(err => { .. });
既然Collection.findById()
returns一个promise,我想我应该使用链接而不是这个结构。
所以它可能类似于
User
.findById(userId)
.then(user => Post.findById(postId))
.then(post => Image.findById(imageId))
.then(image => {
// DO SOMETHING WITH VARIABLES 'user', 'post', AND 'image'
});
.catch(err => { .. });
但我不知道如何访问变量 user
、post
和 image
,也不知道如何抛出错误,因此我可以在 catch
声明。
编辑
我试过了
async function getPostAsync() {
const userId = '597989c668189f31483ffdbf';
const postId = '597989c62624ea74750c74f8';
if (!userId) {
throw new Error('User id missing');
}
if (!postId) {
throw new Error('Post id missing');
}
const user = await User.findById(userId);
const post = await Post.findById(postId);
return post;
}
app.get('/', (req, res) => {
getPostAsync().then(post => {
res.json({
status: 'success',
});
}).catch(err => {
res.status(400).json({
status: 'error',
err
});
})
});
但我刚收到
{
"status": "error",
"err": {}
}
我是不是做错了什么?
但即使使用
我也得到相同的结果
async function getPostAsync() {
throw new Error('msg');
return Post.find();
}
所以我可能调用了错误的异步函数。
您无法在稍后的承诺中访问这些变量 then
,但您可以通过将局部解析值分配给全局变量来绕过它
let globalUser, globalPost; // create variables for later
User
.findById(userId)
.then(user => {
globalUser = user; // assign to global
return Post.findById(postId)
})
.then(post => {
globalPost = post; // assign to global
return Image.findById(imageId)
})
.then(image => {
// DO SOMETHING WITH VARIABLES 'globalUser', 'globalPost', AND 'image'
})
.catch(err => {... });
编辑:或使用async/await
时:
async function() {
const user = await User.findById(userId);
const post = await Post.findById(postId);
const image = await Image.findById(imageId);
// do something with user, post and image
}
鉴于您的承诺不相互依赖,您也可以在异步函数中使用 Promise.all()
:
async function() {
const result = await Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
]);
const [user, post, image] = result;
// do something with user, post and image
}
编辑 2:错误处理
async function getImage() {
let user;
try {
user = await User.findById(userId);
} catch (error) { // deal with rejection of `User.findById`
// do something with error
}
// if these fail the entire function will throw
const post = await Post.findById(postId);
const image = await Image.findById(imageId);
return image;
}
getImage()
.then(image => {... })
.catch(error => {... }); // deal with rejection of `getImage` as a whole
以上代码展示了在异步函数中处理错误的方法。第一个是我们如何处理 User.findById
函数中的错误,只需将其包装在 try catch
块中即可。
第二种方法是简单地让整个异步函数抛出一个错误。 IE。如果 Post.findById
或 Image.findById
承诺拒绝,整个 getImage()
承诺将拒绝,您可以在 .catch()
处理程序中处理。
您可以使用 Promise.all:
Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
])
.then(result)=>{
let user = result[0];
let post = result[1];
let image = result[2];
})
.catch(err => { .. });
Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
])
.then(([user, post, image])=>{...})
.catch(err => { .. });
我如何构造一个函数,其中有多个 Mongoose.findOne()
相互嵌套?
我需要做类似的事情
const userId = '...';
const postId = '...';
const imageId = '...';
User.findById(userId).then(user => {
if (!user) {
return res.status(400).json({
status: 'error',
err: 'User not found',
});
}
Post.findById(postId).then(post => {
if (!post) {
return res.status(400).json({
status: 'error',
err: 'Post not found',
});
}
Image.findById(imageId).then(image => {
if (!image) {
return res.status(400).json({
status: 'error',
err: 'Image not found',
});
// DO SOMETHING WITH VARIABLES 'user', 'post', AND 'image'
}).catch(err => { .. });
}).catch(err => { .. });
}).catch(err => { .. });
既然Collection.findById()
returns一个promise,我想我应该使用链接而不是这个结构。
所以它可能类似于
User
.findById(userId)
.then(user => Post.findById(postId))
.then(post => Image.findById(imageId))
.then(image => {
// DO SOMETHING WITH VARIABLES 'user', 'post', AND 'image'
});
.catch(err => { .. });
但我不知道如何访问变量 user
、post
和 image
,也不知道如何抛出错误,因此我可以在 catch
声明。
编辑
我试过了
async function getPostAsync() {
const userId = '597989c668189f31483ffdbf';
const postId = '597989c62624ea74750c74f8';
if (!userId) {
throw new Error('User id missing');
}
if (!postId) {
throw new Error('Post id missing');
}
const user = await User.findById(userId);
const post = await Post.findById(postId);
return post;
}
app.get('/', (req, res) => {
getPostAsync().then(post => {
res.json({
status: 'success',
});
}).catch(err => {
res.status(400).json({
status: 'error',
err
});
})
});
但我刚收到
{
"status": "error",
"err": {}
}
我是不是做错了什么?
但即使使用
我也得到相同的结果async function getPostAsync() {
throw new Error('msg');
return Post.find();
}
所以我可能调用了错误的异步函数。
您无法在稍后的承诺中访问这些变量 then
,但您可以通过将局部解析值分配给全局变量来绕过它
let globalUser, globalPost; // create variables for later
User
.findById(userId)
.then(user => {
globalUser = user; // assign to global
return Post.findById(postId)
})
.then(post => {
globalPost = post; // assign to global
return Image.findById(imageId)
})
.then(image => {
// DO SOMETHING WITH VARIABLES 'globalUser', 'globalPost', AND 'image'
})
.catch(err => {... });
编辑:或使用async/await
时:
async function() {
const user = await User.findById(userId);
const post = await Post.findById(postId);
const image = await Image.findById(imageId);
// do something with user, post and image
}
鉴于您的承诺不相互依赖,您也可以在异步函数中使用 Promise.all()
:
async function() {
const result = await Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
]);
const [user, post, image] = result;
// do something with user, post and image
}
编辑 2:错误处理
async function getImage() {
let user;
try {
user = await User.findById(userId);
} catch (error) { // deal with rejection of `User.findById`
// do something with error
}
// if these fail the entire function will throw
const post = await Post.findById(postId);
const image = await Image.findById(imageId);
return image;
}
getImage()
.then(image => {... })
.catch(error => {... }); // deal with rejection of `getImage` as a whole
以上代码展示了在异步函数中处理错误的方法。第一个是我们如何处理 User.findById
函数中的错误,只需将其包装在 try catch
块中即可。
第二种方法是简单地让整个异步函数抛出一个错误。 IE。如果 Post.findById
或 Image.findById
承诺拒绝,整个 getImage()
承诺将拒绝,您可以在 .catch()
处理程序中处理。
您可以使用 Promise.all:
Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
])
.then(result)=>{
let user = result[0];
let post = result[1];
let image = result[2];
})
.catch(err => { .. });
Promise.all([
User.findById(userId),
Post.findById(postId),
Image.findById(imageId)
])
.then(([user, post, image])=>{...})
.catch(err => { .. });