繁体   English   中英

事件驱动的编程node.js?

[英]Event driven programming node.js?

我正在阅读本文,我特别怀疑是否有人对我清楚。

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!");
});

您的代码为节点提供了读写文件的两项任务,然后进入睡眠状态。 节点完成任务后,将触发其回调。 但是一次只能触发一个回调。 在该回调完成执行之前,所有其他回调都必须排队等待。 除此之外,不能保证回调的触发顺序。

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

  1. 谁能向我解释以上粗体字? 为什么我们不能担心两个不同的程序将无法访问该对象。
  2. 当前的线程方式怎么会出现问题?
  3. 触发回调的顺序会不会有问题? 让我们让我希望callBack A()在callBack b()之前先返回。

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

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!");
    });
});

请注意,有时这可以使您进入通常称为“回调地狱”的地方

编辑:解决您的评论:

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

2)除了很难阅读之外,回调地狱本质上没有什么坏处。 可能会想到,如果您尝试执行的操作包含多个不同的异步进程(例如,对磁盘进行读写),那么您可能会得到如下所示的内容:

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回调地狱”,那么这里和其他地方都会有很多讨论。 整理内容的一种方法是避免使用内联/匿名函数,并使用命名函数对其进行整理,这样您的回调函数就不会嵌套在编辑器中那么深(尽管从词法的角度来看嵌套仍在进行)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM