【问题标题】:Node: Callback was already called节点:回调已被调用
【发布时间】:2018-09-14 03:24:28
【问题描述】:

我知道这里有几个重复的问题。但是,我不知道如何解决这个问题。我的代码是这样的:

/**
 * DEFINE
 * @connection_kill
 */
apiRoutes.post('/balancer_connection_drop', function(req, res) {
    /* BALANCER - connection kill */
    async.auto({
        decrypt_kill: function(callback, drop, user, stream) {
            /* DROP - decrypt */
            try {
                /* DEFINE - drop */
                var drop = JSON.parse(decrypt(Object.keys(req.body)[0], encryption));

                /* DROP - user & stream */
                callback(null, drop['drop'], drop['user'], drop['stream']);
            } catch(s) {
                /* CLOSE - connection */
                res.end();
            }
        },
        remove_connection: ['decrypt_kill', function(results, callback) {
            /* DROP - balancer || user & stream */
            if ((results[Object.keys(results)[0]])[0] !== 'null') {
                /* DROP - balancer users */
                if (results[Object.keys(results)[0]][0] == 'balancer') {
                    console.log('callback users...');
                    /* DROP - balancer users */
                    pool.query('UPDATE live SET remove=?',[1], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                    })
                } else {
                    console.log('callback user...');
                    /* DROP - balancer user */
                    pool.query('UPDATE live SET remove=? WHERE user=? AND stream=?',[1, results[Object.keys(results)[0]][1], results[Object.keys(results)[0]][2]], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                    })
                }
            } else {
                console.log('failed to kill data empty...');
                return callback('Balancer Connection Kill Data Empty!');
            }
            console.log('callback...');
            callback();
        }]
    }, function(err, results) {
        /* CHECK - error */
        if (err) return res.send(encrypt(JSON.stringify({'status': 'false'}), encryption));
        /* DROP - success */
        res.send(encrypt(JSON.stringify({'status': 'true'}), encryption));
        /* END - connection */
        res.end();
    })
})

现在当我调用这个 api C 从节点得到这个错误:

回调已被调用

所以我输入了代码 console.log 来查看两次调用的内容,然后我从 console.log 中得到了这个,然后它抛出了两次调用的错误:

callback user...
callback...

所以我看到我犯了一个错误,我调用了它两次,但我不知道如何重写上面的代码以在回调 user... 被调用时正常工作。我要去

function(err, results) {

function 并在该函数中将 json 返回到我的服务器 api,但我不知道如何重写它。我尝试使用上面的这段代码将回调移动到函数之外,但从未调用过回调。

【问题讨论】:

    标签: node.js callback


    【解决方案1】:
    • 你在处理 pool.query 中的错误后进行回调

    • 问题是 pool.query 是一个异步任务,节点跳过 推送到 libuv 后的异步任务

    • 它到达pool.query回调函数之前的最后一个callback();

    • 在您的代码到达后调用最后一个回调 pool.query 回调函数

        apiRoutes.post('/balancer_connection_drop', function(req, res) {
    
        /* BALANCER - connection kill */
        async.auto({
            decrypt_kill: function(callback, drop, user, stream) {
                /* DROP - decrypt */
                try {
                    /* DEFINE - drop */
                    var drop = JSON.parse(decrypt(Object.keys(req.body)[0], encryption));
    
                    /* DROP - user & stream */
                    callback(null, drop['drop'], drop['user'], drop['stream']);
                } catch(s) {
                    /* CLOSE - connection */
                    res.end();
                }
            },
            remove_connection: ['decrypt_kill', function(results, callback) {
                /* DROP - balancer || user & stream */
                if ((results[Object.keys(results)[0]])[0] !== 'null') {
                    /* DROP - balancer users */
                    if (results[Object.keys(results)[0]][0] == 'balancer') {
                        console.log('callback users...');
                        /* DROP - balancer users */
                        pool.query('UPDATE live SET remove=?',[1], function(err, results) {
                            /* DROP - failed */
                            if (err){ return callback('Could NOT Drop Users From Live Table!');}
     
                          return callback();
                        })
                    } else {
                        console.log('callback user...');
                        /* DROP - balancer user */
                        pool.query('UPDATE live SET remove=? WHERE user=? AND stream=?',[1, results[Object.keys(results)[0]][1], results[Object.keys(results)[0]][2]], function(err, results) {
                            /* DROP - failed */
                            if (err){ return callback('Could NOT Drop Users From Live Table!');}
    
                               return callback();
                        })
                    }
                } else {
                    console.log('failed to kill data empty...');
                    return callback('Balancer Connection Kill Data Empty!');
                }
                
            }]
        }, function(err, results) {
            /* CHECK - error */
            if (err) return res.send(encrypt(JSON.stringify({'status': 'false'}), encryption));
            /* DROP - success */
            res.send(encrypt(JSON.stringify({'status': 'true'}), encryption));
            /* END - connection */
            res.end();
        })
    })
    

    【讨论】:

    • 好答案。如果您担心自己的英语语法不是 100%,请尝试使用要点
    【解决方案2】:

    pool.query 调用前放置一个return。您的代码执行通过if statement 下降到,

    ...
    console.log('callback...');
    callback();
    

    仅供参考,

    你已经有一个 if-else 捕获所有路径,那么你为什么要有这个?

    ...
    console.log('callback...');
    callback();
    

    【讨论】:

    • 我有这个回调()如果没有回调,如果有错误被调用,回调()调用下一个函数没有错误,..简而言之,当我们没有错误回调时语句 callback() 表示该函数成功完成且没有错误...
    【解决方案3】:
        remove_connection: ['decrypt_kill', function(results, callback) {
            /* DROP - balancer || user & stream */
            if ((results[Object.keys(results)[0]])[0] !== 'null') {
                /* DROP - balancer users */
                if (results[Object.keys(results)[0]][0] == 'balancer') {
                    console.log('callback users...');
                    /* DROP - balancer users */
                    pool.query('UPDATE live SET remove=?',[1], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                    })
                } else {
                    console.log('callback user...');
                    /* DROP - balancer user */
                    pool.query('UPDATE live SET remove=? WHERE user=? AND stream=?',[1, results[Object.keys(results)[0]][1], results[Object.keys(results)[0]][2]], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                    })
                }
            } else {
                console.log('failed to kill data empty...');
                return callback('Balancer Connection Kill Data Empty!');
            }
            console.log('callback...');
            callback();
        }]
    

    因为pool.query 是一个异步操作,所以callback()after console.log('callback...'); 将在它们完成之前被调用。如果他们失败了,他们会再次调用它。

    我会删除最后一个 callback()call 并在每次异步调用运行后调用它,如下所示:

        remove_connection: ['decrypt_kill', function(results, callback) {
            /* DROP - balancer || user & stream */
            if ((results[Object.keys(results)[0]])[0] !== 'null') {
                /* DROP - balancer users */
                if (results[Object.keys(results)[0]][0] == 'balancer') {
                    console.log('callback users...');
                    /* DROP - balancer users */
                    pool.query('UPDATE live SET remove=?',[1], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                        callback();
                    })
                } else {
                    console.log('callback user...');
                    /* DROP - balancer user */
                    pool.query('UPDATE live SET remove=? WHERE user=? AND stream=?',[1, results[Object.keys(results)[0]][1], results[Object.keys(results)[0]][2]], function(err, results) {
                        /* DROP - failed */
                        if (err) return callback('Could NOT Drop Users From Live Table!');
                        callback();
                    })
                }
            } else {
                console.log('failed to kill data empty...');
                return callback('Balancer Connection Kill Data Empty!');
            }
        }]
    

    【讨论】:

    • 我按照你的建议添加了,但我现在从 console.log 获取回调用户......这是正确的,但它现在不会将 api 返回到我的服务器......我会调查原因......
    • 我没有看你代码的业务逻辑,但我假设你需要传递pool.query返回的值。因此,您可能需要在 pool.query 解析后调用 callback(null, results) 并在最后使用这些结果。
    猜你喜欢
    • 1970-01-01
    • 2017-10-13
    • 2016-01-26
    • 1970-01-01
    • 2017-09-03
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多