我知道这已被问了一百万次,但我真的试图打破异步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
?
感谢大家耐心帮助我解决这个非常常见的问题:)
答案 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)
这是代码流动的方式:
答案 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)
这清楚了吗?