【问题标题】:Callback function 'next' is executed automatically without making a call to it回调函数 'next' 会自动执行,无需调用它
【发布时间】:2021-05-16 21:38:14
【问题描述】:

我有这个 POST 方法,它使用 FetchURL 中间件从用户提交的 url 中获取数据。

router.post('/', FetchURL, (req, res) => {

    console.info('data received');
    ...
})

response.ok 为 true 时一切正常,但相反的情况并不完全符合预期。 我不希望在 response.ok 等于 false 时调用 next

但是我看到“data received”记录到控制台,这意味着下一个函数确实被自己调用了。

fetch_url.js

function FetchURL(req, res, next) {
    fetch(req.body.input_url)
        .then(response => {
            if(response.ok) 
                return response.json();

            // else render error message on the client machine
            res.status(response.status)
                .render('index', {
                    errStatus: [response.status, response.statusText]
                });

            /* Throwing an Error here is the only way I could prevent the next callback */
            // throw new Error(`Request failed with status code ${response.status}.`);
        })
        .then(data => {
            req.data = data;
            next();
        })
        .catch(err => console.error(err));
}

我在 expressjs 中间件的 documentation 上找不到任何相关内容。我可以阻止 next 被调用的唯一方法是在服务器上抛出一个错误。

这里的幕后发生了什么?

【问题讨论】:

    标签: express ejs middleware node-fetch


    【解决方案1】:

    在调用 next 之前尝试进行第二次检查,如下所示

    function FetchURL(req, res, next) {
        fetch(req.body.input_url)
            .then(response => {
                if(response.ok) // wrap your response in a temporary object.
                    return { fail: false, data: response.json() } ;
    
                // else render error message on the client machine
                res.status(response.status)
                    .render('index', {
                        errStatus: [response.status, response.statusText]
                    });
    
                /* Instead of throwing an Error, return something indicating error */
                return { fail: true };
            })
            .then(data => {
                // check if previous procedure has failed.
                if(!data.fail) {
                    req.data = data.data;
                    next();
                }
            })
            .catch(err => console.error(err));
    }
    

    【讨论】:

    • 但问题还是一样,“是什么原因导致next的执行?”
    • then method 从 fetch 链接起来。如果先前的异步承诺已成功解决,则使用 resolve/ 返回值调用后面的 thgen。由于您在错误呈现后关闭了回调函数,因此“未定义”将自动解析并传递给随后的 then 方法。
    • 哦,那么可以取消解决下一个promise吗?还是退出链条?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多