Javascript 这种关闭是如何运作的?

Javascript 这种关闭是如何运作的?,javascript,node.js,closures,Javascript,Node.js,Closures,我对javascript没有太多经验,我正在阅读一本node.js书,书中有以下代码 function start(route, handle) { function onRequest(request, response) { var postdata=''; var pathname=url.parse(request.url).pathname; request.setEncoding('utf8'); request.addL

我对javascript没有太多经验,我正在阅读一本node.js书,书中有以下代码

function start(route, handle)
{
  function onRequest(request, response)
  {
      var postdata='';
      var pathname=url.parse(request.url).pathname;

      request.setEncoding('utf8'); 

      request.addListener("data", function(postDataChunkd)
      {
         postdata+=postDataChunkd;
      });

      console.log('Post data: ' + postdata);// <----------------------- HERE

      request.addListener("end", function()
      {
         route(handle, pathname, response, postdata);  

      }); 
}

http.createServer(onRequest).listen(8124);

console.log('Server running on 8124');
}

exports.start=start;
功能启动(路线、手柄)
{
函数onRequest(请求、响应)
{
var postdata='';
var pathname=url.parse(request.url).pathname;
setEncoding('utf8');
addListener(“数据”,函数(postDataChunkd)
{
postdata+=postDataChunkd;
});
console.log('Post data:'+postdata);//
有人能解释一下为什么尽管请求成功,postData变量仍记录为空吗

实际上,它与闭包无关,只是计时。在记录请求时,请求还没有完成(甚至没有得到一个
“data”
回调),因此变量没有任何分配给它的内容。请求异步完成

以下是
onRequest
回调发生的顺序:

  • 将创建变量
    postdata
    pathname

  • postdata
    设置为
    '

  • pathname
    设置为计算
    url.parse(request.url).pathname
    的结果

  • 调用
    request.setEncoding

  • 将创建传递到对
    request.addListener
    的第一个调用中的函数

  • 调用并传递
    “data”
    字符串和上一步创建的函数。此时不执行函数

  • 表达式
    'Post data:'+postdata
    被求值,产生
    'Post data:'
    (正如
    postdata
    '
    ),并传递到
    控制台。log
    将被写入控制台

  • 将创建传递给第二个调用
    request.addListener
    的函数

  • request.addListener
    通过
    “end”
    和上一步创建的函数调用

  • 一段时间后,在步骤6中可能会有一个或多个对函数creaetd的调用,也可能没有

  • 稍后,可能会有一个对步骤8中创建的函数的调用


  • Node.js不会等待addListener函数完成。Node将启动异步函数,然后转到下一行代码。执行时postdata=''。

    使用NodeJS的首要任务是熟悉异步编程的概念。您正在为
    数据添加侦听器>事件,很明显,当您的
    console.log()运行时,该事件还没有发生……将日志记录放在事件处理程序中,您将得到一个有意义的结果。我肯定会更多地关注异步方面。非常感谢!!现在已经非常清楚了!