執行

2013-04-08 21 views
1

假設我有一些代碼,這樣執行

function execute() { 
    var tasks = buildListOfTasks(); 
    // ... 
} 

buildListOfTask創建的功能陣列。函數是異步的,可能會發出HTTP請求或/和執行數據庫操作。

如果任務列表顯示爲空或執行了所有任務,則需要再次重複相同的execute例程。再說一遍,說「無限循環」。所以,它就像應用程序一樣。

我完全可以理解如何在同步世界中實現這一點,但有點困惑如何使它在node.js異步世界中成爲可能。

+0

有用的鏈接,也許https://github.com/creationix/step – 2013-04-08 18:19:57

+0

使用jQuery延期對象的想法。我認爲甚至有一個JavaScript庫可以模仿這個 – Ian 2013-04-08 18:20:47

+0

@AlexWayne是的,它有幫助,但不完全。我熟悉這樣的庫(親自使用異步)。我有點困惑如何「循環」操作。 – 2013-04-08 18:21:50

回答

4

使用async.js和它的隊列對象。

function runTask(task, callback) { 
    //dispatch a single asynchronous task to do some real work 
    task(callback); 
} 
//the 10 means allow up to 10 in parallel, then start queueing 
var queue = async.queue(runTask, 10); 

//Check for work to do and enqueue it 
function refillQueue() { 
    buildListOfTasks().forEach(function (task) { 
    queue.push(task); 
    }); 
}  

//queue will call this whenever all pending work is completed 
//so wait 100ms and check again for more arriving work 
queue.drain = function() { 
    setTimeout(refillQueue, 100); 
}; 

//start things off initially 
refillQueue(); 
+0

看起來真的很接近我所需要的..會嘗試! – 2013-04-08 18:42:09

0

我認爲你必須使用async.js,可能是並行功能。 https://github.com/caolan/async#parallel

在全局回調中,只需調用execute來進行遞歸調用即可。

async.parallel(tasks, 
    function(err, results){ 
     if(!err) execute(); 
    } 
); 
+1

由於最大併發限制,隊列比這更安全一些。例如,如果對buildListOfTasks的調用返回了800個數據庫查詢,則可能會使數據庫陷入癱瘓。 – 2013-04-08 18:40:25

+0

@PeterLyons好點! – 2013-04-08 18:48:20

1

如果你已經熟悉了,async庫,你可以使用​​作爲最終回調重新啓動任務:

function execute(err) { 
    if (!err) { 
     async.series(buildListOfTasks(), execute); 
    } else { 
     // ... 
    } 
} 
+0

是否有可能通過這樣的代碼獲得stackoverflow異常? – 2013-04-08 18:27:06

+2

儘管執行會被調用很多次,但對於這些異步調用,堆棧會在每個異步回調中重置,因此您不會溢出它。 – 2013-04-08 18:35:45

+0

但是,您需要真正查看'err'參數,而不是盲目地將async.series放在緊密的循環中,以防拋出錯誤。 – 2013-04-08 18:41:57