Node.js 如何在不使用try-catch块的情况下处理拒绝的多个异步wait-whle承诺中的错误?

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.

我是一名新的express用户,正在制作用户注册api。在这里,我需要散列用户密码并生成一个随机字符串。这两件事都是由aync/await完成的。如果一个承诺被拒绝,那么它会在错误处理中返回响应,但会显示未处理的拒绝承诺的警告

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块中处理错误。