2015-04-05 87 views
2

我目前正在瀏覽關於Javascript的nodeschool.io教程。這是來自其中一個解決方案的示例代碼。在javascript函數中異步與同步。 (Node.js)

module.exports = function (dir, filterStr, callback) { 

    fs.readdir(dir, function (err, list) { 
    if (err) 
     return callback(err) 

    list = list.filter(function (file) { 
     return path.extname(file) === '.' + filterStr 
    }) 

    callback(null, list) 
    }) 
} 

據我所知,javascript是一種同步語言。但是,node.js使用異步函數。在這段代碼中,回調在if語句之前是不可能發生的。因此,有即使任何理由具有功能是從格式不同

function(params, callback){ 
     // one line data manipulation 
     callback(); 
    } 
+1

我不確定你在問什麼。 你能澄清一下你的意思嗎?在if語句之前回調不可能發生。「? – brianjob 2015-04-05 01:14:12

+0

我通常使用java和C++等語言編程。在這些語言中,函數總是從上到下運行,除非您專門告訴他們。然而,node.js是異步的。據我所知,這些功能並不是從上到下運行。我在說有沒有可能,「如果(錯誤)返回...「開始運行,但」回調(null,list)「首先完成 – bigyellowduck 2015-04-05 01:20:52

+1

如果有錯誤(即'err'是一個真值),則執行'callback(err)'並且函數返回''callback(null,list)''在這種情況下永遠不會被調用。至於你的第二段代碼,如果一行數據操作需要一些處理時間,這種情況可能是有意義的,在這種情況下,你不想停止整個程序在等待它完成時 – JCOC611 2015-04-05 01:27:56

回答

0

一個超時或甚至事件被觸發或消息是收到的,這意味着經過一個適當的異步函數通常會調用回調它不會讓等待的線程忙碌,留下一個承諾。在你的例子中,腳本將在你分配回調之後繼續,並且會在異步函數的工作完成時調用它,這很可能會在代碼的其餘部分完成後調用它。

+2

它反映得很好'fs.readdir'是一個異步函數,它接受一個在異步作業完成後會運行的回調函數 – 2015-04-05 01:31:15

+0

你'我沒有意識到他在調用fs.readd ir'在那裏。 – 2015-04-05 01:38:04

3

節點是單線程和基於事件的。 I/O是異步完成的。當你調用fs.readdir()時,你傳遞一個函數對象作爲參數。把它看作是C++中的一個函數指針。 fs.readdir()將啓動一個異步操作並將該函數對象傳遞給事件處理函數,該函數將在I/O操作完成後觸發。

現在,它不會等待I/O操作完成,它只會繼續執行代碼直到它完成,然後返回到偵聽事件。

當它接收到I/O操作完成時觸發的事件時,它將運行它傳遞的函數對象中的代碼。

由於其單線程性質,您不必擔心這些類型的競爭條件。

1

據我瞭解,JavaScript是一種同步語言

我覺得你在這裏誤解的東西。 Javascript是一個單線程語言。但是這並不能使它同步。運行中的幾乎每個環境(包括當前最大的瀏覽器和Node.js)都爲異步處理提供全局事件隊列。

如果我理解你的問題,我也猜你在這裏混淆水平。這裏公開的總體模塊通過接受只會異步調用的回調來提供自己的異步行爲。但是,這是建立在另一個異步塊上,呼叫fs.readdir。該回調函數是構成大部分代碼示例的匿名函數。此回調包含if-聲明。另一個從外部傳入,並命名爲callback,將按照它出現在內部函數內部的相同順序發生,即在if之後。