无法掌握callback的时机

我知道这已被问了一百万次,但我真的想分解asynchronous的Javascript函数和callback,而不是点击。 我正在看马克斯·奥格登的节点艺术的例子是这样的:

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) 

打破这一点,我明白,当addOne被调用时,它首先启动fs.ReadFile ,这可能需要一些时间才能完成。

我不明白的是,代码不会继续callback()并执行logMyNumber (在添加myNumber之前)吗? 什么是阻止callback()运行之前它应该,这是整个点? 或者,直到doneReading发生, callback()才会发生? 我们是否应该假设在fs.readFile “完成”时会调用fs.readFile

谢谢大家的耐心帮助我解决这个非常常见的问题:)

“我们是否应该假设fs.readFile”完成“时会调用doneReading?

你不必假设它,你可以很确定。 您可以使用日志logging来查看代码执行的顺序和顺序。

 var fs = require('fs') console.log("starting script"); console.log("message 1"); function addOne(callback) { fs.readFile('number.txt', function doneReading(err, fileContents) { console.log("finished loading the file"); console.log("message 2"); callback() }) } console.log("message 3"); //logMyNumber will be called after file has read function logMyNumber() { console.log("message 4"); } console.log("message 5"); addOne(logMyNumber) console.log("message 6"); 

理解asynchronous行为的一个更简单的方法是使用所有熟悉的定时器

 console.log("message 1"); var num = 2; function something() { console.log("message 2"); } function somethingElse() { console.log("message 3"); } console.log("message 4"); setTimeout(something, 1000); console.log("message 5"); setTimeout(somethingElse, 500); 

//代码将不会从上到下运行1 – 4 – 5 – 3 – 2,这种方式显然是为什么。 //在文件中读取其原因相同

这是代码的stream动方式:

  1. 你调用addOne(logMyNumber)将被执行。
  2. addOne将读取一个文件, 一旦文件被读取,它会然后
  3. 在“doneReading”函数中执行代码,然后调用你的callback函数(logMyNumber)

查看fs.readFile的第二个参数? 这是一个名为doneReading的函数。

fs.readFile将在完成读取文件时才执行完成读取。 当doneReading被执行时,最后一行是调用callback() ,在这种情况下,它是对logMyNumber函数的引用。

fs.readFile将调用给定的callback,即。 阅读完成后,在代码中完成读取。 这就是Node.js通常如何与callback一起工作的原因:你给完成asynchronous操作后运行的callback。

 // callback is a parameter to addOne // callback is a function, but functions are just objects in javascript // so the addOne function just knows that it has one parameter, not that // callback is a function function addOne(callback) { // callback is now captured in the closure for the doneReading function fs.readFile('number.txt', function doneReading(err, fileContents) { myNumber = parseInt(fileContents) myNumber++ // callback is executed here // But we are inside the doneReading function // which is itself a callback to the fs.readFile function // therefore, it does not get executed until the file has finished reading callback() }) } // similarly, logMyNumber has not been called, it has just been defined // as a function (object)... function logMyNumber() { console.log(myNumber) } // ...and passing logMyNumber to addOne here does not execute it addOne(logMyNumber) 

这是清除它吗?