首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在node.js回调中维护作用域?

如何在node.js回调中维护作用域?
EN

Stack Overflow用户
提问于 2010-12-05 15:49:06
回答 4查看 12.6K关注 0票数 19

我是一名经验丰富的软件开发人员,但对于JS和node来说,我还是个新手。我不是超级嵌套代码的狂热爱好者,所以我一直在尝试将回调分解到它们自己的函数中。不过,我在弄清楚如何在回调触发时维护作用域时遇到了问题。深入研究后,我读到如果我在回调上创建一个闭包,它将会工作,但它似乎不会以我预期的方式工作。

这是一个非常简单的代码版本,它对我来说不起作用:

function writeBody()
{
    res.end("<h1> Hooray! </h1>");
}

http.createServer(function(req, res)
{
    res.writeHead('Content-Type', 'text/html');
    setTimeout(function(){writeBody()}, 2000);
}).listen(8000);

我以为通过将writeBody()调用包装在function()闭包中,我就可以在超时后获得所需的作用域,但是当writeBody()触发时,我得到

ReferenceError:未定义res

谁能告诉我我做错了什么愚蠢的事情?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-12-05 16:09:54

基本上不是闭包是如何工作的,函数继承了它们的外部作用域,这就是它的工作方式。

// this function only inherits the global scope
function writeBody()
{
    res.end("<h1> Hooray! </h1>");
}

http.createServer(function(req, res) // a new local varaible res is created here for each callback
{
    res.writeHead('Content-Type', 'text/html');
    // annonymous function inheris both the global scope
    // as well as the scope of the server callback
    setTimeout(function(){

        // the local variable res is available here too
        writeBody()

    }, 2000);
}).listen(8000);

要使其工作,只需将res对象传递到函数中,因为它在超时回调中可用。

function writeBody(res)
{
    // NOT the same variable res, but it holds the same value
    res.end("<h1> Hooray! </h1>");
}

http.createServer(function(req, res)
{
    res.writeHead('Content-Type', 'text/html');
    setTimeout(function(){
        writeBody(res); // just pass res
    }, 2000);
}).listen(8000);

但是你需要注意这样的事情:

for(var i = 0; i < 10; i++) { // only one i gets created here!()
    setTimeout(function() {
        console.log(i); // this always references the same variable i
    }, 1000);
}

这将打印10十次,因为引用是相同的,并且i会一直递增到10。如果你想拥有不同的数字,你需要为每个数字创建一个新的变量,方法是将setTimeout封装到匿名的self函数中,并将其作为参数传递给i,或者调用一些其他方法来设置timouet并将i作为参数接收。

// anoynmous function version
for(var i = 0; i < 10; i++) {
    (function(e){ // creates a new variable e for each call
        setTimeout(function() {
            console.log(e); 
        }, 1000);
    })(i); // pass in the value of i
}

// function call version
for(var i = 0; i < 10; i++) {
    createTimeoutFunction(i);
}
票数 37
EN

Stack Overflow用户

发布于 2010-12-09 19:08:32

您还可以使函数嵌套,以便它们共享作用域,即

http.createServer(function(req, res)
{

    function writeBody()
    {
        res.end("<h1> Hooray! </h1>");
    }

    res.writeHead('Content-Type', 'text/html');
    setTimeout(function(){writeBody()}, 2000);
}).listen(8000);

我经常发现这比总是传递一堆变量来保持作用域更容易,尽管这意味着你不能在其他地方重用函数。

票数 3
EN

Stack Overflow用户

发布于 2012-08-17 04:25:34

你可以在你的回调中传递响应,这样:

http.createServer(function(req, res)
{
    res.writeHead('Content-Type', 'text/html');
    setTimeout(function(){writeBody(res)}, 2000);
}).listen(8000);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4357881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档