回调不会从函数返回

时间:2014-10-23 20:05:54

标签: javascript node.js

我遇到了这个奇怪的问题,我可能会想到一些非常基本的问题...... 我正在使用Express编写NodeJs中的Javascript。

考虑这条简单的路线。

client.get('/test', function(req, res, next) {
    return next(new Error('This is a error'));
    console.log ('This code will not be executed');
    res.send('This code will not be executed');
});

正如您可能看到此路由将直接调用next()并将控制权传递给错误处理程序。将输出错误(res.json)并且请求结束。 路线中的第一行将被执行......就像它应该的那样。

现在让我们将路由器中的第一行更改为:

client.get('/test', function(req, res, next) {
    hlpr.deadSimple('stop here', function (err) {
        if (err) return next(err);
    });
    console.log ('I dont want this code to be executed, but it will be...');
    res.send('This code shall not be executed either');
});

function deadSimple看起来像这样,并从hlpr.js

导出
module.exports.deadSimple = function (val, callback) {
    if (val === 'stop here') {
        callback(new Error('This is a error!')); 
        // I have also tried "return callback(new Error('This is a error!'));" 
    }
};

如果我尝试此代码,则会创建一个错误,并且似乎调用了错误处理程序,它会输出错误,但似乎控件被传递回路由处理函数!...因为{{1执行。

为什么我的deadSimple函数将控制权传递回路由处理程序?

我应该怎么写这个以我想要的方式工作......那就是如果deadSimple生成错误,这个错误将触发从路由处理函数直接返回,将控制传递给错误处理程序,从而输出错误... NOT 将控制权传递给路由处理程序!

修改

我错过了一些非常基本的东西,即匿名函数中的返回语句作为回调传递仅从自身返回,而不是来自周围路线处理函数。

如果我将console.log和res.send移动到回调中,它们将不会被执行因为在它们有可能被执行之前返回回调函数。当回调只包含同步代码时(就像这样),它将在回调下面的代码执行之前完成。

表明我的观点...这是按预期工作的:

console.log

2 个答案:

答案 0 :(得分:1)

尝试将其他代码放在事件处理程序中,因此只有在if语句为false时才会运行:

client.get('/test', function(req, res, next) {
    hlpr.deadSimple('stop here', function (err) {
        if (err) return next(err);
        console.log ('I dont want this code to be executed, but it will be...');
        res.send('This code shall not be executed either');
    });
});

答案 1 :(得分:1)

你几乎是对的。在您的示例中:

client.get('/test', function(req, res, next) {
    hlpr.deadSimple('stop here', function (err) {
        if (err) return next(err);
    });
    console.log ('I dont want this code to be executed, but it will be...'); //this line is executed right away
    res.send('This code shall not be executed either'); 
});

它首先执行hlpr.deadSimple,它需要一个回调。但是如果你想在执行下一个函数之前等待这个回调,你需要将它们放在你的回调函数中:

client.get('/test', function(req, res, next) {
    hlpr.deadSimple('stop here', function (err) { //everything inside this function will be executed only when it calls back
        if (err) return next(err);
        console.log ('I dont want this code to be executed, but it will be...');
        res.send('This code shall not be executed either');
    });

});

让我尝试用一​​个简单的类比来解释(它存在于这个网站的某个地方,但我无法找到它......):

您正在工作,并且需要您的同事吉姆在整个城市的文件,以填写表格。你拿起你的手机打电话给吉姆,吉姆说:“我会看看,我会给你回电话。”然后你挂断电话,去喝杯咖啡。过了一会儿,吉姆给你回电话,然后给你提供信息。然后,您可以填写表格。

上述情况可写为:

Jim.call(function(info){
    fillForm(info)        //that's the part you do only when your colleague calls back
}
haveBreak();  // That's the action you take just after calling Jim, before he calls you back