2015-09-13 48 views
1

有人可以带我了解所有回调的情况吗?我是Node新手,并且迷路了!我在下面评论了一些混乱的来源。了解节点回调

var utils = require('./utils'); 

"POST": function(request, response) { 
     //collect the data 




     utils.collectData(request, function(message) { 
      message.objectID = ++objectIDcounter; 
      messages.push(message); 
      utils.sendResponse(response, { 
       objectID: message.objectID 
      }, 201) 
     }) 
    } 
    // this is in utils.js: 
    //why is a callback parameter passed to this function? 
    exports.collectData = function(request, callback) { 
     var data = "" 
     request.on('data', function(chunk) { 
      data += chunk; 
     }) 
     request.on('end', function() { 
    //why is the callback applied here? 
//Also, we are parsing the data here. why? because it is a buffer or a string here? 
       callback(JSON.parse(data)); 
      }) 
     } 

回答

3

为什么回调参数传递给这个函数?

request.on()安装一个事件处理程序,它将在某个时间后被调用(例如将来某个任意时间)。在调用事件处理程序之前,.collectData()方法将返回。

因此,只有在收到的所有数据的结果都是要调用回调函数时,request.on('end', ...)事件处理程序表示现在已收集所有数据。

让我们的日志报表工具这一点,也许这会给你一个想法事件的顺序是如何工作的:

console.log("before collectData()"); 
    utils.collectData(request, function(message) { 
     console.log("in collectData() callback"); 
     message.objectID = ++objectIDcounter; 
     messages.push(message); 
     utils.sendResponse(response, { 
      objectID: message.objectID 
     }, 201) 
    }) 
} 
console.log("after collectData()"); 

// this is in utils.js: 
//why is a callback parameter passed to this function? 
exports.collectData = function(request, callback) { 
    console.log("in collectData() method"); 
    var data = "" 
    request.on('data', function(chunk) { 
     console.log("in request.on('data', ...)"); 
     data += chunk; 
    }) 
    request.on('end', function() { 
     console.log("in request.on('end', ...)"); 
     callback(JSON.parse(data)); 
    }) 
} 

有了这些console.log()报表,你会在调试控制台得到这个序列:

before collectData() 
in collectData() method 
after collectData() 
in request.on('data', ...) 
in request.on('data', ...) 
in request.on('data', ...) 
in request.on('end', ...) 
in collectData() callback 

您可以看到collectData()运行并结束,但事件处理程序仍然存在,因为随着传入数据的到达,它们将完成工作,然后最终在'end'事件到达时s,所有的数据都已经完成,并且可以调用回调来传回最终的数据累积。

这是node.js中I/O的异步性质。您开始一个操作,设置一些监听器或回调,然后node.js库使用各种OS服务在后台执行实际的I/O操作。与此同时,其他node.js代码可以继续运行,稍后,I/O操作将完成并在node.js事件队列中插入一个事件。当当前执行的JS线程完成它正在做的任何事情时,node.js引擎会将下一个事件从事件队列中拉出并触发与该事件关联的任何回调,从而允许一些node.js代码为该事件提供服务。 node.js的创建者将此称为“已知的I/O”。

虽然这个答案为浏览器写的,事件队列和概念,它是如何使用和管理是相同的node.js中那么这个答案可以帮助你更好地理解:How does JavaScript handle AJAX responses in the background?及制品,其还可以帮助: Understanding the node.js event loop

为什么在这里应用回调?

当接收到'end'事件时,告知代码现在已收到所有数据。此请求不会再有'data'事件。此时,您知道您现在拥有所有数据,因此这是回调被称为最终数据累积的地方。

此外,我们在这里解析数据。为什么?因为这是一个缓冲区还是一个 字符串?

我不能在此刻找到collectData()的文件,但现在看来,它期待一个JSON字符串是数据,因此它被认为解析JSON字符串,因此它可以返回相应的JavaScript对象。