无法掌握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动方式:
- 你调用addOne(logMyNumber)将被执行。
- addOne将读取一个文件, 一旦文件被读取,它会然后
- 在“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)
这是清除它吗?