我如何在node.js中创build一个非阻塞的asynchronous函数?

我如何创build一个非阻塞的asynchronous函数? 下面是我正在努力实现,但我的程序仍然阻止…

var sys = require("sys"); function doSomething() { sys.puts("why does this block?"); while(true); } setTimeout(doSomething,0); setTimeout(doSomething,0); setTimeout(doSomething,0); sys.puts("main"); 

从Reddit交叉发布。


JavaScript中asynchronous函数的用途与您所寻求的有些不同。

请记住,JavaScript是单线程的 – 一次只能做一件事。 以下是一些传统的阻止代码:

 sys.puts("Before"); sleep(10); sys.puts("After"); 

在真实世界的Web应用程序中, sleep()可能是一个耗时的数据库调用,networking请求(如等待来自用户的Web浏览器的数据),辅助工具或文件访问。

如果你使用上面的阻塞调用,那么Node.js服务器在等待的时候就不能做任何事情(比如开始处理其他web请求)。

PHP和许多其他Web编程环境通过为每个请求创build完全独立的线程来处理这个问题。 Node.js使用callback函数。 你可以这样编写相同的代码:

 sys.puts("Before"); setTimeout(function(){ sys.puts("After"); }, 10000); 

在这里,你创build一个函数并把它传递给setTimeout() 。 它的代码还没有运行,但是当它运行时,它将可以访问创build它的所有范围(所有variables)。 setTimeout()获取对该函数的引用,并在超时到期之后调度在事件循环上触发的事件 。

事件循环本质上是一个Node.js程序的待办事项列表(它们很常见 – 您的计算机上运行的所有GUI应用程序都可能使用事件循环!)。

在调用setTimeout() ,当前函数继续执行。 它最终返回,并调用它的函数返回,等等,直到程序结束回事件循环。 事件循环查看代码执行时是否发生了任何事情(例如传入的请求),并在代码中调用适当的函数。 如果没有,它会等待,直到发生事情(如超时过期)。

asynchronous代码不会让你的代码同时做很多事情,当一些代码依赖于某些外部的继续时,它确实消除了阻塞。

你很less需要在Node.js程序中阻塞工作。 如果你这样做,你应该把这个工作分解成一个独立的进程(甚至可以是另一个Node.js程序),或者编写一个可以自由使用线程的C / C ++插件 。

只能通过使用由C ++编写的node.js运行时或node.js扩展提供的asynchronousIO函数在node.js中执行asynchronousIO。 您自己的Javascript代码在node.js中始终是同步的。 非同步的非IO代码是很less需要的,而node.jsdevise者决定完全避免它。

在其他评论者提到的node.js中有一些asynchronous运行Javascript的方法,但是node.js并不是为这种types的工作而devise的。 如果你需要这种types的并发,使用Erlang,node.js只是和平的IO,而对于并行计算来说,它和Python或PHP一样糟糕。

您需要在单独的进程中运行阻塞函数。

这个模块可以帮助: http : //github.com/cramforce/node-worker

如果您不想使用WebWorker API / node-worker(仍然非常简单),只需创build一个附加的节点程序并通过TCP或HTTP进行通信即可。

这使您可以将您的工作分配为HTTP调用或原始TCP数据,并asynchronous等待HTTP响应/传入TCP答案。

但请注意,只有在您的任务易于序列化时才适用。

setTimeout不会创build一个新的线程,所以浏览器将仍然挂在无限循环。

你需要重新考虑你的程序结构。

你可以在不使用subprocess的情况下使用nextTick()

有一天,我刚刚阅读了关于nextTick的这个解释…这是一个很棒的IMO读物

http://howtonode.org/understanding-process-next-tick

如果我明白你在做什么之后,你有两个函数(都以callback为参数):

process.nextTick :这个函数可以被堆栈,这意味着如果它被recursion地调用,它将循环每个事件循环的tick的巨大的( process.maxTickDepth )次数。

要么

setImmediate :这个函数更接近于设置0超时(但是之前发生)。

在大多数情况下,你应该更喜欢setImmediate。

我假设你正在试验Nodejs我也假设你没有写任何npm模块本身和导出你的function作为asynchronousfunction,在实际中,你不会遇到这种情况下,如果你想做任何阻止操作的function或在单线程环境中执行的callback中,尽量使用fs等适当的节点模块进行文件读取,请求networking请求,并给出各种types的asynchronous操作的asynchronous模块,还要记住你试图asynchronous执行cpu消费代码这是一个坏主意,因为2HZ可以在短短的几微秒内执行一百万行代码

nodejs的主要目的是为了解决在底层libuv处理asynchronous事件的问题中你所问的问题,我很欣赏使用set time的答案,但是你不知道要等多less时间或使用节点工作者是好的,但最终你会写很多的锅炉板代码,所以只需要searchnpm模块,以满足您的需要。

这一行:

 while(true); 

不是“阻塞”,它只是忙碌,永远。