Javascript 异步错误捕获器包装函数,导致返回的承诺未定义

Javascript 异步错误捕获器包装函数,导致返回的承诺未定义,javascript,node.js,asynchronous,promise,Javascript,Node.js,Asynchronous,Promise,我正在构建一个api,并尝试使用req.cookie创建一些cookie 最初,我遇到了一个问题,在我的scynchronous代码中发送响应之前,cookies没有全部设置好: const createTokensAndCookies = catchAsync(async (req, res) => { const promises = []; promises.push(jwtToken.sign({ id: req.user._id })); promises

我正在构建一个api,并尝试使用
req.cookie
创建一些cookie

最初,我遇到了一个问题,在我的scynchronous代码中发送响应之前,cookies没有全部设置好:

const createTokensAndCookies = catchAsync(async (req, res) => {
    const promises = [];
    promises.push(jwtToken.sign({ id: req.user._id }));
    promises.push(jwtRefreshToken.create());
    promises.push(csrfToken.create());
    const tokens = await Promise.all(promises);
    //create coookies
    jwtCookie.create(req, res, tokens[0]);
    jwtRefreshCookie.create(req, res, tokens[1]);
    csrfCookie.create(req, res, tokens[2]);

});

在一个路由处理程序中,我调用了这个函数,在下一行中调用了
res.send()

为了解决这个问题,我做出了
createTokensAndCookies
返回一个承诺。因此,我的代码是:

const createTokensAndCookies = catchAsync(async (req, res) => {
    const promises = [];
    promises.push(jwtToken.sign({ id: req.user._id }));
    promises.push(jwtRefreshToken.create());
    promises.push(csrfToken.create());
    const tokens = await Promise.all(promises);
    //create coookies
    return new Promise((resolve, reject) => {
        jwtCookie.create(req, res, tokens[0]);
        jwtRefreshCookie.create(req, res, tokens[1]);
        csrfCookie.create(req, res, tokens[2]);
        resolve();
    });
});
路由处理程序:

exports.signUp = catchAsync(async (req, res, next) => {
    //get only certain variables out of req object
    const { body } = req;

    const user = await User.create({
        name: body.name,
        email: body.email,
        password: body.password,
        passwordConfirmation: body.passwordConfirmation,
    });
    req.user = user;
    createTokensAndCookies(req, res).then(() => {
        res.status(201).json({
            status: 'success',
        });
    });
});
catchAsync
包装器:

module.exports = (fn) => (req, res, next) => {
    fn(req, res, next).catch(next);
};
我现在得到以下错误:
无法读取未定义的属性“then”

有趣的是,当我删除
catchAsync
包装时,所有的东西都工作了,直到创建了所有cookie之后才发送响应


有人知道我如何在保持
catchAsync
warpper的同时做到这一点吗?请解释为什么删除catchAsync包装器可以解决此问题。您的错误似乎发生在这一行:

createTokensAndCookies(req, res).then(() => {
问题是
createTokensAndCookies()
不会返回任何内容。解决此特定问题的一个简单解决方案可能是,您可以这样更改它以返回承诺:

module.exports = (fn) => (req, res, next) => {
    return fn(req, res, next).catch(next);
};
但是,我认为主要的问题是您在
createTokensAndCookies
内部使用了
catchAsync
。请注意,您实际上是在传递一个只有2个参数的函数,其中需要3个参数。抓两次似乎是多余的。您可以而且应该只传递从路由处理程序中的
createTokensAndCookies
(没有
catchAsync
)返回的承诺。因此,请删除catchAsync:

const createTokensAndCookies = async (req, res) => {
    const promises = [];
    promises.push(jwtToken.sign({ id: req.user._id }));
    promises.push(jwtRefreshToken.create());
    promises.push(csrfToken.create());
    const tokens = await Promise.all(promises);
    //create cookies
    jwtCookie.create(req, res, tokens[0]);
    jwtRefreshCookie.create(req, res, tokens[1]);
    csrfCookie.create(req, res, tokens[2]);
};
并按如下方式更改路由处理程序:

exports.signUp = catchAsync(async (req, res, next) => {
    // ...
    return createTokensAndCookies(req, res).then(() => {
        res.status(201).json({
            status: 'success',
        });
    });
});
我怀疑您希望在
createCookiesAndTokens
中保留
catchAsync
,因为您在其他地方将其用作路由处理程序。如果是这种情况,只需将其包装在
catchAsync
中即可。这样
createCookiesAndTokens
实际上会返回一个承诺,当出现问题时,该承诺将失败。这是人们在阅读代码时所期望的,它使函数更加可重用。

“为了解决我提出的
createTokensAndCookies
返回承诺的问题”
async
函数已经返回了承诺(它使用的是
wait
),添加了
返回新承诺((resolve,reject)=>{…resolve();})绝对不会改变任何东西。“有人知道我如何在保持
catchAsync
warpper的同时做到这一点吗?”-不,这毫无意义。为什么要将其保留在
createTokensAndCookies
定义中?只能在路由处理程序周围使用
catchAsync