Callbacks are functions that are executed asynchronously, or at a later time.Node中几乎所有的东西都使用了回调函数,但他不是node发明的,他们是JavaScript的一部分,判断一个函数是同步还是异步的取决于他的上下文环境。
同步:像看书一样从上向下读,上一行定义函数,下一行立即执行。
var Mynum=1;
function addOne(){Mynum++;}
addOne();
console.log(Mynum);//2
异步:
var fs = require('fs'); //fs是node的核心模块,通过require加载该模块
var myNumber = undefined ;// 不知道myNumber是否存储在file中
function addOne() {
fs.readFile('number.txt', function doneReading(err, fileContents) {
myNumber = parseInt(fileContents);
myNumber++;
})
}
addOne()
console.log(myNumber) //undefined
原因是我们在该代码中使用了异步的fs.readFile()方法,它是由node提供的异步方法,需要很长时间去完成,所以没有等到readFile()获取到文件的内容时就已执行console.log打印mynumber的值。
当addOne()函数调用时,他开始fs.readFile()方法,然后继续执行后续的代码,如果没有代码要执行,node将会等待处理的fs / network操作完成,否则将停止运行并退出到命令行。
若要取得预期的运行结果,就需要使用回调函数
当我们运行程序时,所有的函数都是立刻定义的,但却不是立即执行的。这是理解异步编程的基础。理解回调函数的关键是当你不知道异步操作什么时候完成,但你知道一步操作在哪完成时(异步函数的最后一行)使用回调函数。
声明回调函数时代码的从上到下顺序并不重要,重要的是他的逻辑/层次化嵌套。首先将代码分解成函数,其次如果一个函数依赖于另一个函数的完成就将其声明为回调函数。
var fs = require('fs');
var myNumber = undefined;
function addOne(callback) {
fs.readFile('number.txt', function doneReading(err, fileContents) {
myNumber = parseInt(fileContents);
myNumber++;
callback();
})
}
function logMyNumber() {
console.log(myNumber)
}
addOne(logMyNumber);//2
logMyNumber()函数可以作为参数传入并将成为addOne()函数里的callback()变量;在readFile完成后,callback()被调用,打印出myNumber的值。