Node.js 如何在不使用try-catch块的情况下处理拒绝的多个异步wait-whle承诺中的错误?
我是一名新的express用户,正在制作用户注册api。在这里,我需要散列用户密码并生成一个随机字符串。这两件事都是由aync/await完成的。如果一个承诺被拒绝,那么它会在错误处理中返回响应,但会显示未处理的拒绝承诺的警告Node.js 如何在不使用try-catch块的情况下处理拒绝的多个异步wait-whle承诺中的错误?,node.js,express,Node.js,Express,我是一名新的express用户,正在制作用户注册api。在这里,我需要散列用户密码并生成一个随机字符串。这两件事都是由aync/await完成的。如果一个承诺被拒绝,那么它会在错误处理中返回响应,但会显示未处理的拒绝承诺的警告 methods.signup = async (req,res,next) => { const errors = validationResult(req); if (!errors.isEmpty()) { return res.
methods.signup = async (req,res,next) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(config.errorCodes.validation).json({errors:errors.array()});
}
let payload = req.body;
var newUser = new User({
username:payload.username,
fullname:payload.fullname,
email: payload.email,
password: payload.password,
urltoken:{
token:null
},
actStatus: 0,
provider: 'email',
role:1
});
let hash = commonMethods.generatePasswordHash(payload.password);
let token = commonMethods.createRandomString();
let [a,b] = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
newUser.password = a;
newUser.urltoken.token = b;
newUser.save(function(err){
if(err) {
return res.status(config.errorCodes.success).json({ status:false
,msg:"Error in saving userdata. Please try again",err});
}
else {
commonMethods.sendMail(newUser);
return res.status(config.errorCodes.success).json({"status":true,
"msg":"Registered succesfully. Please Check your Email to verify
your account.",newUser})
}
});
}
承诺是-
commonMethods.createRandomString = function(password){
return new Promise(function(resolve, reject) {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 25;
var randomstring = '';
for (var i=0; i<string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum,rnum+1);
}
reject(randomstring);
// resolve(randomstring);
})
}
如何在不使用try-catch或then-for-promissions的情况下捕获这些错误,并使代码简单易读。问题在于行
let [a,b] = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
如果hash
或token
抛出,则进入.catch
函数,但catch
函数不返回任何内容:因此,在wait
和catch
完成后,解释器将看到如下内容
let [a,b] = undefined
const result = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
if (!result) return;
let [a,b] = result;
这将不起作用(undefined
不可修改),因此整个.signup
方法将被拒绝。如果哈希
或令牌
中出现错误,则需要某种方法让注册
函数的其余部分知道停止执行,可能类似于
let [a,b] = undefined
const result = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
if (!result) return;
let [a,b] = result;
您说您不想使用try
/catch
,但这样做的逻辑可能会更容易一些,因为您可以从catch
内部立即返回:
let a, b;
try {
([a, b] = await Promise.all([hash,token]));
} catch(e) {
return res.status(400).json({status:false,msg:"error in promise"});
}
问题在于线路
let [a,b] = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
如果hash
或token
抛出,则进入.catch
函数,但catch
函数不返回任何内容:因此,在wait
和catch
完成后,解释器将看到如下内容
let [a,b] = undefined
const result = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
if (!result) return;
let [a,b] = result;
这将不起作用(undefined
不可修改),因此整个.signup
方法将被拒绝。如果哈希
或令牌
中出现错误,则需要某种方法让注册
函数的其余部分知道停止执行,可能类似于
let [a,b] = undefined
const result = await Promise.all([hash,token]).catch(err=>{
res.status(400).json({status:false,msg:"error in promise"})
});
if (!result) return;
let [a,b] = result;
您说您不想使用try
/catch
,但这样做的逻辑可能会更容易一些,因为您可以从catch
内部立即返回:
let a, b;
try {
([a, b] = await Promise.all([hash,token]));
} catch(e) {
return res.status(400).json({status:false,msg:"error in promise"});
}
API编码惯例建议
1)有两种方法可以巧妙地处理错误。第一种方法是使用try-catch块包装所有异步路由,该块将处理同步和异步代码错误
异步/等待
methods.foo = async(req, res, next) => {
try {
// assuming bizz is a utility analogous to createRandomString
// and returns a promise object which will either get resolved or rejected
// if resolved the response will end in this case and end the response
// if rejected, await will throw an error which will be caught by the catch block
var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)
// {... DO SYNCHRONOUS STUFF ...}
// if suppose there is an error in your synchronous code,
// then it will throw an error which also will be caught by the catch block
res.end();
} catch (err) {
// {... DO WHAT YOU NEED TO WITH THE ERROR CAUGHT BY EITHER Asynchronous OR Synchronous part of the method ...}
console.log(err);
res.end(err);
}
}
2)第二种方法是使用一个中间件包装所有路由,从而避免重写所有路由的try-catch。在这里,同步和异步错误都将由异步中间件中的.catch()部分处理
使用异步等待中间件
const asyncMiddleware = (asyncFunction) => {
return (req, res, next) => {
Promise.resolve(asyncFunction(req, res, next))
.catch((err) => {
// DO STUFF WITH ERROR
res.end(err);
});
}
};
methods.foo = asyncMiddleware((req, res, next) => {
// assuming bizz is a utility analogous to createRandomString
// and returns a promise object which will either get resolved or rejected
// if resolved the response will end in this case and end the response
// if rejected, await will throw an error which will be caught by asyncMiddleware
var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)
// {... DO SYNCHRONOUS STUFF ...}
// if suppose there is an error in your synchronous code
// then it will throw an error which also will be caught by asyncMiddleware
res.end();
});
API编码惯例建议
1)有两种方法可以巧妙地处理错误。第一种方法是使用try-catch块包装所有异步路由,该块将处理同步和异步代码错误
异步/等待
methods.foo = async(req, res, next) => {
try {
// assuming bizz is a utility analogous to createRandomString
// and returns a promise object which will either get resolved or rejected
// if resolved the response will end in this case and end the response
// if rejected, await will throw an error which will be caught by the catch block
var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)
// {... DO SYNCHRONOUS STUFF ...}
// if suppose there is an error in your synchronous code,
// then it will throw an error which also will be caught by the catch block
res.end();
} catch (err) {
// {... DO WHAT YOU NEED TO WITH THE ERROR CAUGHT BY EITHER Asynchronous OR Synchronous part of the method ...}
console.log(err);
res.end(err);
}
}
2)第二种方法是使用一个中间件包装所有路由,从而避免重写所有路由的try-catch。在这里,同步和异步错误都将由异步中间件中的.catch()部分处理
使用异步等待中间件
const asyncMiddleware = (asyncFunction) => {
return (req, res, next) => {
Promise.resolve(asyncFunction(req, res, next))
.catch((err) => {
// DO STUFF WITH ERROR
res.end(err);
});
}
};
methods.foo = asyncMiddleware((req, res, next) => {
// assuming bizz is a utility analogous to createRandomString
// and returns a promise object which will either get resolved or rejected
// if resolved the response will end in this case and end the response
// if rejected, await will throw an error which will be caught by asyncMiddleware
var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)
// {... DO SYNCHRONOUS STUFF ...}
// if suppose there is an error in your synchronous code
// then it will throw an error which also will be caught by asyncMiddleware
res.end();
});
或者,如果promise总是返回带有错误属性和数据的resolve对象,我们可以试试吗。然后我们可以检查a.err&&b.err?在制作API时,使用async/await或promise/哪一种方法更好?async await使代码更清晰、更容易理解,并承诺/然后使代码更冗长!如果需要,您可以执行.catch(err=>err)
然后检查错误的结果实例。这取决于你,我没有偏好(即使在代码风格方面我通常有偏好:)。然后
s和await
s在不同的情况下会导致代码更短。-比如我们有依赖的承诺链。。然后我们应该使用。然后,如果我们需要带有承诺的独立结果,我们可以使用async/await?或者我们可以尝试一下如果承诺总是返回带有错误属性和数据的resolve对象。然后我们可以检查a.err&&b.err?在制作API时,使用async/await或promise/哪一种方法更好?async await使代码更清晰、更容易理解,并承诺/然后使代码更冗长!如果需要,您可以执行.catch(err=>err)
然后检查错误的结果实例。这取决于你,我没有偏好(即使在代码风格方面我通常有偏好:)。然后
s和await
s在不同的情况下会导致代码更短。-比如我们有依赖的承诺链。。然后我们应该使用。然后,如果我们需要有承诺的独立结果,我们可以使用async/await?nice。但我不明白第二条路。!异步中间件充当每个路由的包装器。例如,如果应用程序中有5条路由,那么按照第一种方法,我们需要在每个路由的try-catch块中处理错误。相反,假设我们将其包装在一个中间件上。现在,对该路由的每个调用都将由中间件提供服务。因此,中间件本身接受一个异步函数,该函数本质上是一个快速路由,并将其封装在一个承诺中。如果承诺拒绝或同步部分在路由中抛出了一些错误,则asyncMiddleware中的.catch部分将处理这两个错误。但我不明白第二条路。!异步中间件充当每个路由的包装器。例如,如果应用程序中有5条路由,那么按照第一种方法,我们需要在每个路由的try-catch块中处理错误。