无法掌握回调的时机

时间:2013-11-08 20:03:38

标签: javascript node.js callback

我知道这已被问了一百万次,但我真的试图打破异步Javascript函数和回调,而不是单击。我正在看Max Ogden的Art of Node示例:

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()在它应该运行之前停止运转,这是重点?或者callback()doneReading发生之前不会发生?我们是否应该假设doneReading“完成”后会调用fs.readFile

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

5 个答案:

答案 0 :(得分:2)

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

你不必假设它,你可以非常肯定它。 您可以使用日志记录来查看代码执行的方式和顺序。

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");

// <强> _ __ _ __ _ __ _ __ _ _ 理解异步行为的一种更简单的方法是使用所有熟悉的计时器

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不是从上到下,这种方式显而易见的原因。 //在文件中读取它的原因相同

答案 1 :(得分:0)

这是代码流动的方式:

  1. 您将调用addOne(logMyNumber)执行。
  2. addOne将读取文件,读取文件后将
  3. 执行“doneReading”函数中的代码,然后调用你的回调函数(即logMyNumber)

答案 2 :(得分:0)

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

fs.readFile只有在读完文件后才会执行doneReading。执行doneReading后,最后一行是调用callback(),在这种情况下,这是对logMyNumber函数的引用。

答案 3 :(得分:0)

fs.readFile将调用给定的回调,即。阅读完成后,在您的代码中完成阅读。这就是Node.js通常如何处理回调:你给出了在完成异步操作后运行的回调。

答案 4 :(得分:0)

// 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)

这清楚了吗?