2012-03-05 109 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