2016-04-04 122 views
2

我想了解的異步代碼的conept,讓我產生了以下代碼:的JavaScript:異步函數

"use strict"; 
var fs = require("fs"); 
var buf = new Buffer(1024); 

console.log("Global Start"); 
console.log("+++ Async open - truncate - close: open file2 called"); 
fs.open("file2.txt", "r+", function (err, fd) { 
    console.log(" Global + 1 Start"); 
    if (err) { 
    return console.error(err); 
    } 
    console.log(" +++ Async file2 opened successfully!"); 

    // Truncate the opened file. 
    console.log(" +++ Async open - truncate - close: truncate file2 called"); 
    fs.ftruncate(fd, 10, function (err) { 
    console.log("  Global + 2 Start"); 
    if (err) { 
     console.log(err); 
    } 
    console.log("  +++ truncate file2 successfully!"); 
    console.log("  +++ Async open - truncate - close: read file2 called"); 
    fs.read(fd, buf, 0, buf.length, 0, function (err, bytes) { 
     console.log("   Global + 3 Start"); 
     if (err) { 
     console.log(err); 
     } 
     // Print only read bytes to avoid junk. 
     if (bytes > 0) { 
     console.log("   Global + 3 +++ truncate read: '" + buf.slice(0, bytes).toString() + "'"); 
     } 

     // Close the opened file. 
     console.log("   Global + 3 +++ truncate - open - close: close file2 called"); 
     fs.close(fd, function (err) { 
     console.log("    Global + 4 Start"); 
     if (err) { 
      console.log(err); 
     } 
     console.log("    Global + 4 ++++++++++++++++++++ Async open - truncate - close file2 + closed ++++++++++++++++++++"); 
     console.log("    Global + 4 End"); 
     }); 

     console.log("   Global + 3 End"); 
    }); 
    console.log("  Global + 2 End"); 
    }); 
    console.log(" Global + 1 End"); 
}); 
console.log("Global End"); 

從而創立了下面的輸出。

Global Start 
+++ Async open - truncate - close: open file2 called 
Global End 
     Global + 1 Start 
     +++ Async file2 opened successfully! 
     +++ Async open - truncate - close: truncate file2 called 
     Global + 1 End 
       Global + 2 Start 
       +++ truncate file2 successfully! 
       +++ Async open - truncate - close: read file2 called 
       Global + 2 End 
         Global + 3 Start 
         Global + 3 +++ truncate read: 'This is a ' 
         Global + 3 +++ truncate - open - close: close file2 called 
         Global + 3 End 
           Global + 4 Start 
           Global + 4 ++++++++++++++++++++ Async open - truncate - close file2 + closed ++++++++++++++++++++ 
           Global + 4 End 

所以這是我做的是:


  1. 全球範圍有: 「全球開始」
  2. 調用具有一個回調函數fs.open fs.open時被執行已經完成了。
  3. fs.open開始工作,而不是等待結果,而是執行全局級別的下一個任務,即「全局結束」。

  4. 現在完成fs.open並調用回調函數。我們輸入全球+1範圍。

  5. 全球+ 1範圍: 「全球+ 1開始」 有一個回調函數

  6. 呼叫fs.ftruncate時fs.ftruncate完成

  7. fs.ftruncate開始工作那得到執行,當它工作時,Global + 1範圍的其餘代碼被執行,即「Global + 1 End」。

  8. 當fs.ftruncate完成時,它的回調函數被調用。

Global + 3和Global + 4遵循相同的模式。


所以我的問題是;

是我對代碼中發生的事情的描述是否正確?

在我看來像異步代碼是從最外層的括號(全局範圍)執行到最內層的括號(全局+4範圍)。它不是從最內層到外層(像數學一樣),也不是從頂層到頂層(如同步代碼)。那是對的嗎?

如果全局作用域上的某個函數完成並在全局作用域上的其他代碼完成之前執行其回調函數,會發生什麼情況。回調是否等待全局代碼完成?

如果使用不同的文件執行相同的代碼以處理需要不同時間處理的輸出,那麼輸出的結果會以不同的順序出現嗎?

+1

你的描述基本上是正確的,但我建議忘記括號和天氣的東西是執行最內層或最外層。你在描述中缺少的東西是** time **。異步回調僅在稍後的**時間執行**。對我而言,最好的方式就是像告訴視頻(或PVR)錄像機的說明一樣:在「稍後」錄製,然後繼續當前的功能(這是爲了向我展示電視上的內容) – slebetman

回答

2

你對此有很好的把握。至於你的問題:

  1. 「在我看來,像異步代碼是從最外支架(全球範圍)執行到最內側支架」

異步調用將執行像任何其他命令,而不是等待結果,下面的命令會被執行。下一個命令是異步回調之後的直接行,除非有某種函數調用。 「

  1. 」回調會等待全局代碼結束嗎?「

全局範圍變量不會等待異步調用,反之亦然。代碼將運行,並且稍後依賴異步調用中的變量的代碼可能會或可能不會獲取這些變量的更新版本。這取決於異步通話是否按時完成。

  1. 「如果使用不同的文件執行相同的代碼來處理需要不同時間處理的輸出,輸出結果會以不同的順序出現嗎?

同樣,執行代碼的順序取決於異步調用的速度。代碼將始終以相同的順序讀取。爲了防止毆打你的異步調用,你要確保所有依賴異步調用的JS進入回調中,因爲它會等待直到異步完成。

我相信我回答了您的所有問題,如果我錯過了某些內容,任何人都會發表評論。