gpt4 book ai didi

javascript - Node.js 在回调中调用回调函数

转载 作者:行者123 更新时间:2023-11-28 19:28:21 25 4
gpt4 key购买 nike

我最近通过阅读《Node JS in Action》一书开始学习node.js。这可能是一个新手问题,但是在阅读了几篇关于回调函数和 javascript 变量范围的文章之后,我仍然无法理解本书第 5 章中这段代码背后的想法。

function loadOrInitializeTaskArray(file, cb) {
fs.exists(file, function(exists) {
var tasks = [];
if (exists) {
fs.readFile(file, 'utf8', function(err, data) {
if (err) throw err;
var data = data.toString();
var tasks = JSON.parse(data || '[]');
cb(tasks);
});
} else {
cb([]);
}
});
}

function listTasks(file) {
loadOrInitializeTaskArray(file, function(tasks) {
for(var i in tasks) {
console.log(tasks[i]);
}
});
}

它包括三个回调函数,分为两个函数。首先调用 listTasks(..) ,然后调用 loadorInitializeTaskArray(.. ) 。我的问题从这里开始,这个调用是如何由 Node 处理的? loadOrInitializeTaskArray 有两个参数,第二个是回调函数,根据签名,它不应该接受任何参数,但它确实接受!!
cb(..) 何时在 loadorInitializeTaskArray 中被调用,那是什么(与调用辅助函数的函数相同)?

“tasks”是在函数loadOrInitializeTaskArray中声明的数组,我们如何在listTasks(..)函数中访问它?

我知道在 Javascript 中,变量的作用域是在它定义的函数和所有嵌套函数内部。但我在这里很难理解它。那么有人可以解释一下这是怎么回事吗?谢谢

最佳答案

您确实很难理解嵌套函数内变量的范围。那么,让我们开始吧。
让我们考虑一下这段代码

function foo(){
var a = 3;
function bar(){
console.log(a);
}
return bar;
}
var baz = foo();
baz(); // the value of a i.e 3 will appear on console

如果您了解 C、C++ 等语言...您的大脑会像这样解释此代码。如果您不知道其中任何一个,请忽略这些要点。

  • foo()被调用时,变量a将被声明并赋值3。
  • foo返回时,包含a的堆栈将被销毁。因此 a 也会被销毁。
  • 那么 baz() 究竟是如何输出 3 的。 ???

嗯,在 javascript 中,当调用一个函数时,发生的事情与在 C 中不同。因此,在进一步阅读之前,首先让所有 C 事情从你的脑海中消失。

在 JavaScript 中,作用域解析是通过沿着一系列对象链向下移动来完成的,这些对象定义了该代码“作用域内”的变量。让我们看看如何?

  • 当您声明全局 JavaScript 变量时,您实际上所做的是定义全局对象的属性。
  • 在顶级 JavaScript 代码(即不包含在任何函数定义中的代码)中,作用域链由单个对象(全局对象)组成。
  • 在非嵌套函数中,作用域链由两个对象组成。第一个是定义函数参数和局部变量的对象,第二个是全局对象。
  • 在嵌套函数中,作用域链具有三个或更多对象。当定义一个函数时,它会存储当时有效的作用域链。当调用该函数时,它会创建一个新对象来存储其局部变量,并将该新对象添加到存储的作用域链中,以创建一个新的、更长的链来表示该函数调用的作用域。

所以,当执行 foo() 时。它创建一个新对象来存储其局部变量。因此,变量 a 将存储在该对象中。并且,还定义了 bar。当 bar 被定义时,它存储有效的作用域链。因此, bar 的作用域链现在包含具有变量 a 的对象。因此,当返回 bar 时,它会引用其作用域链。因此它知道a

所以,我想它回答了你的问题 Node 如何处理代码。

你写道:

loadOrInitializeTaskArray takes two arguments and the second one is the callback function which shouldn't accept any parameters according to is signature but it does!!

回调函数为

function(tasks) {
for(var i in tasks) {
console.log(tasks[i]);
}
}

它接受一个参数tasks。所以,你错了。

loadOrIntializeTaskArray被调用时,cb指的是这个回调函数。 cb(arg) 基本上执行此 tasks = arg 操作,其中tasks 是回调函数中的参数。

我想您仍然会有很多问题。请在评论中告诉我。我强烈建议您在深入了解 Node 之前先浏览一下 Core Javascript。

关于javascript - Node.js 在回调中调用回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27393206/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com