2012-06-20 53 views
8

所以我想知道什麼是一個更好的方式(在堆棧增長和性能方面)以遞歸方式定期調用一個函數?例如,假設我想每200毫秒讀取文件內容。我有以下兩種方法,並想知道他們是否有什麼不同?定期遞歸調用函數

方法1:使用純醇的setTimeout不process.nextTick

var fs = require('fs'); 
(function loop() { 
    // Print to time to indicate something is happening 
    console.log(new Date().toString()); 

    // Read a 51MB file 
    fs.readFile('./testfile', function (err, data) { 
    if (err) console.log(err); 
    }); 

    // Call the same function again 
    setTimeout(function() { 
    loop(); 
    }, 200); 
})(); 

方法2:調用process.nextTick裏面的setTimeout

var fs = require('fs'); 
(function loop() { 
    // Print to time to indicate something is happening 
    console.log(new Date().toString()); 

    // Read a 51MB file 
    fs.readFile('./testfile', function (err, data) { 
    if (err) console.log(err); 
    }); 

    // Call the same function again 
    setTimeout(function() { 
    process.nextTick(function() { 
     loop(); 
    }); 
    }, 200); 
})(); 

我想知道的是,裏面加入process.nextTick setTimeout是否有用?調用process.nextTick中的函數是否會緩解堆棧使用情況?

+2

不回答你,但你絕對應該把'setTimeout'在你的'readFile'的回調中。 –

+1

我在這裏看不到任何遞歸調用。循環調用在發生超時事件時調用,而不是在函數內部調用。直到loop()返回 – jcoder

回答

28

有一個在下面的簡單示例沒有遞歸:

function test() 
{ 
    console.trace(); 
    setTimeout(test, 1000); 
} 

test(); 

輸出(注意堆棧並沒有增長)

Trace 
    at test (/private/tmp/rec.js:3:12) 
    at Object.<anonymous> (/private/tmp/rec.js:7:1) 
    at Module._compile (module.js:449:26) 
    at Object..js (module.js:467:10) 
    at Module.load (module.js:356:32) 
    at Function._load (module.js:312:12) 
    at module.js:487:10 
    at EventEmitter._tickCallback (node.js:238:9) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
Trace 
    at Object.test [as _onTimeout] (/private/tmp/rec.js:3:12) 
    at Timer.ontimeout (timers.js:101:19) 
+0

+1完美答案後才能調用。我正在刪除我的。 –