簡體   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