2

我知道这已经被问了一百万次,但我真的试图分解异步 Javascript 函数和回调,它只是没有点击。我正在查看 Max Ogden 的节点艺术示例,它是这样的:

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“完成”时调用?

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

4

5 回答 5

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 而不是从上到下,这很明显为什么。//在文件中读取其相同的原因

于 2013-11-08T20:10:05.077 回答
0

这是代码流动的方式:

  1. 您调用 addOne(logMyNumber) 将被执行。
  2. addOne 将读取一个文件,一旦文件被读取,它将
  3. 执行“doneReading”函数中的代码,该函数又会调用您的回调(即 logMyNumber)
于 2013-11-08T20:06:54.580 回答
0

看到第二个参数fs.readFile? 它是一个名为 的函数doneReading

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

于 2013-11-08T20:07:49.690 回答
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)

这样就清楚了吗?

于 2013-11-08T20:10:54.203 回答
0

fs.readFile 将调用给定的回调,即。阅读完成后在您的代码中完成阅读。这就是 Node.js 通常使用回调的方式:您提供在完成异步操作后运行的回调。

于 2013-11-08T20:10:39.470 回答