gpt4 book ai didi

javascript - 事件驱动编程node.js?

转载 作者:太空宇宙 更新时间:2023-11-04 02:54:04 26 4
gpt4 key购买 nike

我正在阅读这篇文章,我有一个特别的疑问是否有人向我澄清。

http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb

var fs = require('fs')
, sys = require('sys');

fs.readFile('treasure-chamber-report.txt', function(report) {
sys.puts("oh, look at all my money: "+report);
});

fs.writeFile('letter-to-princess.txt', '...', function() {
sys.puts("can't wait to hear back from her!");
});

您的代码为 Node 提供了读取和写入文件的两个任务,然后进入休眠状态。一旦 Node 完成任务,就会触发它的回调。但同一时间只能触发一个回调。在该回调完成执行之前,所有其他回调都必须排队等待。除此之外,无法保证回调的触发顺序。

“所以我不必担心代码同时访问相同的数据结构?”你说对了!这就是 JavaScript 单线程/事件循环设计的全部魅力!

  1. 谁能给我解释一下上面的粗体线条吗?为什么我们不能担心两个不同的程序无法访问该对象。
  2. 为什么当前的线程方式有问题?
  3. 回调的触发顺序会有问题吗?假设我希望callBack A() 在callBack b() 之前先返回。

最佳答案

1) 如果您运行单线程,则不必担心多线程应用程序带来的问题。这包括 2 个不同的线程尝试同时使用同一个对象。例如,想象一下,如果一个线程尝试从哈希中读取数据,而另一个线程正在从同一哈希中删除数据。键/值对可能看起来像是存在于一行代码中,但由于线程化,当它到达下一行时,数据可能不再存在。同样,您不必处理所有额外的代码和避免这些问题所涉及的麻烦。

2) 参见#1。这与其说是一个问题,不如说是一个权衡。如今,许多计算机都具有多个处理器/内核,因此让一个程序一次使用多个线程可能是有益的。当您预计线程会阻塞时,它也很有用。例如,在另一种多线程语言中,读取文件的内容并在不添加回调的情况下输出它们是很常见的。然而,这意味着线程坐在那里什么也不做(被阻塞),直到文件读取操作完成。多线程编程也很难正确完成。

3) 您不会得不到保证订单。如果您想确保顺序正确,请等待第一个调用返回后再执行第二个调用。例如

fs.readFile('treasure-chamber-report.txt', function(report) {
sys.puts("oh, look at all my money: "+report);

fs.writeFile('letter-to-princess.txt', '...', function() {
sys.puts("can't wait to hear back from her!");
});
});

请注意,这有时会让您陷入通常所说的“回调 hell ”

编辑:解决您的意见:

1) 尽管您正在“等待”NodeJS 读取文件,但在 NodeJS 中,这是一个非阻塞操作。这意味着方法调用 (readFile) 会立即返回,甚至在读取文件之前也是如此。这是因为它将数据 IO 请求传递给底层操作系统,底层操作系统有自己的线程来处理此类请求。当操作系统完成读取(或写入)时,它会通知原始进程它已准备好数据。当操作系统正在执行这项工作时,NodeJS 可以让它的一个线程在等待时继续执行其他工作。这就是为什么你需要回调 - 当你最终获得数据时,你需要一种方法来告诉 NodeJS 接下来要做什么。

2) 回调 hell 本身并没有什么坏处,只是难以阅读。人们可能会想象,如果您尝试执行的操作包括多个不同的异步进程(例如读取和写入磁盘),那么您可能会得到如下所示的结果:

var doSomething function(){
fs.readFile('step1.txt', function(result){
// do something with the result
fs.writeFile('step2.txt', function(){
// okay, step2 is ready, so process that
fs.readFile('step2.txt', function(result){
fs.writeFile('step3.txt', function(){
//etc, etc
});
});
});
});
}

您可以看到嵌套很快就会变得相当深,并且变得难以阅读。如果您搜索“JavaScript 回调 hell ”,这里和其他地方有很多讨论讨论这个问题。扁平化的一种方法是避免内联/匿名函数,并使用命名函数扁平化它,这样你的回调就不会在编辑器中嵌套得那么深(尽管从词法的 Angular 来看,嵌套仍然发生)。

关于javascript - 事件驱动编程node.js?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13365213/

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