2012-03-05 82 views
2

。:免責聲明:Node.js - 在另一個線程中暫停腳本執行

請注意,我正在嘗試用node.js來實現某些可能違背其設計原則的東西。然而,由於node.js違背了「JavaScript是爲了客戶端」的規範,我也在嘗試不同的東西。請多多包涵。

。:背景:

我有一個要求,即對於簡單的用戶來說,簡單的腳本需要敘述Java腳本(從頭到尾)。我還將爲更高級的用戶提供異步腳本功能。

我瞭解node.js的事件驅動方法,並且有一個基於異步回調的解決方案。現在我正試圖簡化這些,以滿足我們更基本的腳本要求。

。:問題:

有沒有一種方法可以運行腳本(使用自己的沙箱),可以在執行結果被傳遞時暫停執行。

E.g.

var util = require('util'), 
vm = require('vm'), 
user = require('user'); 

vm.runInThisContext('user.WaitForProceed(); console.log('Waiting over');'); 

console.log('Finished!'); 

用戶是我自己的模塊,將會等待。基本上我希望它坐在那裏並阻止vm對象中的那一行,直到它收到結果爲止。之後它將繼續到console.log行。

這個例子的輸出不重要,因爲它也可以通過回調來實現。示例腳本的敘述性質對於此解決方案更爲重要。

  • Ĵ
+0

那麼誰聲稱這就是所謂的NORM(!?)「javascript是爲了客戶端」 - 還是說你(和其他人)只能在那裏看到它,並宣稱你/他們知道的唯一東西就是「規範」?無論如何,沒有辦法可以暫停。 JS機器繼續運行事件循環,只有在沒有任何運行的情況下才會停止。所以停下來的唯一方法是不要再有代碼,也不要再有更多的事件(附帶一個事件監聽器)。你唯一能做的就是等待這個「繼續」事件。 – 2012-03-05 07:39:10

+0

...所以你必須有一個事件來聽,由你的「用戶」對象解僱。但是你說你已經有了這樣一個解決方案,所以重要的是你要從這個JS引擎本身實際工作,然後你會對這個東西有更好的感覺:)你應該告訴我們更多關於什麼user.WaitForProcceed()does;) – 2012-03-05 07:52:36

+0

「...因此,重要的是你要從這個JS引擎本身實際工作...」規範是別人告訴我的東西「應該工作」。我瞭解節點的侷限性和功能,但是與所有開發人員打交道的情況一樣。但他們希望以他們的方式使用這個系統。我只是探索什麼是可能的。 – Nevar 2012-03-06 22:05:11

回答

8

沒有辦法以暫停在節點的執行。至少,他們告訴我們,以便:)

有一些支持先進的流量控制,如Invoke,也許這可以幫助圖書館,但我明白,這不是你問什麼:)

而且你可以執行忙循環使用nextTick()

或者您可以在C(++)中實現阻塞調用並將其作爲庫提供。我從來沒有這樣做過。

最後一種方法是將readFileSync()添加到在certian事件中關閉的namedpipe。

正如您已經提到的那樣,這是針對語言principes,因此這些解決方案都是hacky。

+1

有。使用本機Node.js插件...查看我的答案。 – 2012-03-06 06:45:40

+0

用於readFileSync /管道解決方案的+1。偷偷摸摸,聰明。 – 2013-03-02 16:42:56

+0

readFileSync正是我想要的破解 – Prospero 2013-05-27 05:51:44

2

如果您真的想在等待結果時暫停執行,您可以嘗試使用node-sync。它建立在node-fibers。您的應用程序需要使用節點光纖腳本而不是節點來執行。 node-sync將同步方法添加到允許同步運行的Function.prototype。

此外,您還需要將您的呼叫包裹在光纖(線程)中,以免阻塞事件循環。

var Sync = require('sync'); 

var someAsyncFunction = function(a, b, callback) { 
    setTimeout(function() { 
     var result = a + b; 
     callback(undefined, result); 
    }, 1000); 
}; 

// Run in a fiber 
Sync(function(){ 
    // This code runs in separate fiber and does not block the event loop 

    // First argument is 'this' context 
    var result = someAsyncFunction.sync(null, 2, 3); 
    // Waiting one second 
    console.log(result); // Will output 5 
}); 

// Event loop here 

請注意它。你需要明白這不是節點的方式。

+0

非常好。可悲的是我需要主腳本在同步函數調用中停止執行,然後在稍後的日期被要求重新開始。這對我需要實現的其他事情很有用。也許我可以使用它作爲虛擬機的跑步者並暫停該光纖。我會玩一玩。 – Nevar 2012-03-06 22:12:15

+0

如果您需要在功能正常工作時停止執行主事件循環,只需刪除Sync(function(){});來自示例的封裝。這應該暫停主要事件循環。 – 2012-03-06 22:36:51

7

如果你真的想睡眠節點進程的執行,你可以。但是,正如你所述,似乎你完全意識到了這種影響。

這裏是一個NPM模塊做到這一點: https://github.com/ErikDubbelboer/node-sleep

您可以使用它像這樣:

var sleep = require('sleep'); 
sleep.sleep(1); //sleep for 1 sec 
sleep.usleep(2000000); //sleep for 2 sec 

我部分寫這爲,通過谷歌搜索到達未來的用戶: 你不應該使用上述技術。如果您決定必須這樣做,請注意這會阻止您的節點進程,並且在睡眠期結束之前它將無法執行任何其他工作。此外,由於Node.js程序假定爲非阻塞,您將違反任何意識到它是Node.js程序的用戶的期望。

祝你好運。

+0

謝謝!我想知道這是否仍然暫停主要的消息循環,如果你分叉vm關閉。問題仍然是我需要別的東西來喚醒分離過程。也許纖維(下面會提到)會有很好的效果。 – Nevar 2012-03-06 22:16:38

+0

恩,Erik Dubbelboer的睡眠模塊真的很糟糕。它非常不可接受。 – 2013-05-24 17:48:57

+0

1)他沒有說他需要Windows的解決方案。2)這是一年前發佈的。 3)最重要的是,試圖暫停Node.js執行線程幾乎在所有情況下都是一個糟糕的主意。 – 2013-05-24 19:34:38