繁体   English   中英

异步错误捕获器包装器 function 导致我返回的 promise 未定义

[英]asynchronous error catcher wrapper function causing my returned promise to be undefined

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

最初我遇到了一个问题,因为在我的同步代码中发出响应之前,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]);

});

然后在路由处理程序中调用此 function 并在下一行调用res.send()

为了解决这个问题,我让createTokensAndCookies返回了 promise。 所以我的代码是:

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);
};

我现在收到以下错误: Cannot read property 'then' of undefined

有趣的是,当我删除catchAsync包装器时,一切正常,并且在创建所有 cookies 之前不会发送响应。

有谁知道我如何在保持catchAsync变形器的同时做到这一点? 解释为什么删除catchAsync包装器可以解决问题也很好。

您的错误似乎发生在这一行:

createTokensAndCookies(req, res).then(() => {

问题是createTokensAndCookies()不返回任何内容。 解决此特定问题的简单修复可能是您将其更改为返回 promise:

module.exports = (fn) => (req, res, next) => {
    return fn(req, res, next).catch(next);
};

但是,我认为主要问题是您在createTokensAndCookies中使用catchAsync 请注意,您实际上传递的 function 只有 2 个参数,而预期为 3 个。 抓两次似乎是多余的。 您可以并且应该只传递从路由处理程序内的createTokensAndCookies (没有catchAsync )返回的 promise 。 所以删除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',
        });
    });
});

我怀疑您想将catchAsync保留在createCookiesAndTokens中,因为您在其他地方使用它作为路由处理程序。 如果是这种情况,只需将其包装在catchAsync中即可。 这样createCookiesAndTokens实际上会返回一个 promise,当出现问题时会失败。 这是人们在阅读代码时所期望的,它使 function 更具可重用性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM