简体   繁体   中英

Event driven programming node.js?

I was going through this article, i have one particular doubt if some one clear out to me.

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

Your code gives node the two tasks to read and write a file, and then goes to sleep. Once node has completed a task, the callback for it is fired. But there can only be one callback firing at the same time. Until that callback has finished executing, all other callbacks have to wait in line. In addition to that, there is no guarantee on the order in which the callbacks will fire.

"So I don't have to worry about code accessing the same data structures at the same time?" You got it! That's the entire beauty of JavaScripts single-threaded / event loop design!

  1. Can anyone explain me the above bold lines.? How come we are not able to worry that the two different programs would not access the object.
  2. How come the current way of threading has problem?
  3. Will the order of firing the callback's be a problem? Let's take i want callBack A() to return first before callBack b().

1) If you're running single threaded, you don't have to worry about the problems that come with a multi-threaded application. This includes 2 different threads trying to use the same object at the same time. Imagine, for example, if one thread was trying to read data from a hash, while another thread was deleting data from the same hash. A key/value pair may look like it was present in one line of code, but because of threading by the time it reaches the next line the data may not be there anymore. Similarly, you don't have to deal with all the extra code and headaches involved in avoiding these problems.

2) See #1. It's not a problem so much as a tradeoff. Lots of computers these days have multiple processors/cores, so having a program use more than one thread at a time can be beneficial. It is also useful when you expect a thread to be blocking. For example, in another multi-threaded language it would be common to read the contents of the file, and the output them without the addition of a callback. However, this means that thread sits there doing nothing (blocked) until the file read operation is done. Multi-threaded programming is also very hard to do correctly.

3) You wouldn't not be gauranteed order. If you want to ensure proper order, you wait to execute the 2nd call until the first has returned. eg

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

Note that this can sometimes get you into what is commonly referred to as 'callback hell'

EDIT: To address your comments:

1) Even though you are "waiting" for NodeJS for the file to be read, in NodeJS this is a non-blocking operation. That means the method call ( readFile ) returns immediately, even before the file is read. This is because it passes off the data IO request to the underlying operating system, which has it's own threads for processing such requests. When the operating system finishes the read (or write), it notifies the originating process that it is ready with the data. While the operating system is doing this work, NodeJS can let it's one thread continue on doing other work while it waits. That's why you need the callback - you need a way to tell NodeJS what to do next when you finally get the data.

2) There is nothing inherently bad about callback hell, other than it is hard to read. One might imagine that if what you are trying to do includes several different asynchronous processes (like reading and writing to disk), that you might get something that looks like this:

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

You can see that nesting can get rather deep rather quickly, and get difficult to read. If you search for "JavaScript callback hell" there are many discussions here and elsewhere that talk about this. One approach to flatten things out is to avoid inline/anonymous functions, and flatten it out with named functions, so you callbacks are not nested so deep in your editor (though the nesting is still happening from a lexical standpoint).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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