首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >事件驱动编程node.js?

事件驱动编程node.js?
EN

Stack Overflow用户
提问于 2012-11-13 17:02:36
回答 1查看 2.7K关注 0票数 0

我读过这篇文章,我有一个特别的疑问,如果有人向我澄清。

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

代码语言:javascript
复制
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!");
});

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

“那么我就不用担心代码同时访问相同的数据结构了吗?”!这就是JavaScripts单线程/事件循环设计的全部美!

  1. 有人能解释我上面的粗体台词吗?为什么我们不能担心这两个不同的程序将无法访问对象。
  2. 为什么现在的线程方式会有问题呢?
  3. 启动回调的顺序会有问题吗?让我们假设我希望callBack A()首先返回callBack b()。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-13 17:14:23

1)如果您运行的是单线程,则不必担心多线程应用程序所带来的问题。这包括两个不同的线程,试图同时使用同一个对象。例如,假设一个线程试图从哈希读取数据,而另一个线程从相同的哈希中删除数据。键/值对看起来可能在一行代码中存在,但由于到下一行时线程化,数据可能不再存在。类似地,您不必处理避免这些问题所涉及的所有额外代码和头痛。

2)见#1,与其说这是一个问题,不如说是一个权衡。现在很多计算机都有多个处理器/核,所以一个程序一次使用多个线程是有益的。当您期望线程被阻塞时,它也很有用。例如,在另一种多线程语言中,通常会读取文件的内容,并在不添加回调的情况下输出它们。但是,这意味着在文件读取操作完成之前,线程在那里什么都不做(阻止)。多线程编程也很难正确执行。

( 3)你不会不服从命令的。如果您希望确保正确的顺序,则等待执行第二个调用,直到第一个调用返回。例如:

代码语言:javascript
复制
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)从本质上讲,回调地狱没有什么不好之处,只是它很难读懂。人们可能会想象,如果您要做的工作包括几个不同的异步进程(比如读取和写入磁盘),那么您可能会得到如下所示的内容:

代码语言:javascript
复制
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回调地狱“,这里和其他地方都会讨论这个问题。一种将事情扁平化的方法是避免内联/匿名函数,并使用命名函数将其扁平化,这样您的回调就不会嵌套在编辑器中那么深的位置(尽管从词汇的角度来看嵌套仍然在进行)。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13365213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档