如何在node.js中创建非阻塞异步函数?
如何创建非阻塞异步函数?下面是我试图实现的目标,但我的程序仍然被阻塞如何在node.js中创建非阻塞异步函数?,node.js,Node.js,如何创建非阻塞异步函数?下面是我试图实现的目标,但我的程序仍然被阻塞 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"); setTimeo
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");
setTimeout
不会创建新线程,因此浏览器仍将挂起在无限循环处
您需要重新考虑您的程序结构。您需要在单独的进程中运行阻塞功能 此模块可以帮助:此行:
while(true);
不是“阻塞”,它只是永远忙碌。如果您不想使用WebWorker API/node worker,它仍然是alpha,只需创建一个额外的节点程序并通过TCP或HTTP进行通信 这允许您以HTTP调用或原始TCP数据的形式分派工作,并异步等待HTTP响应/传入TCP应答
但是,如果您的任务容易序列化,这是合适的。 < P>您只能使用C++编写的No.js运行时或NoDE.js扩展提供的异步IO函数来完成NoDE.js中的异步IO。您自己的Javascript代码在node.js中始终是同步的。异步非IO代码很少需要,node.js设计者决定根本不使用它 其他评论员提到,node.js中有一些神秘的异步运行Javascript的方法,但node.js不是为这种工作而设计的。如果您需要这种类型的并发,请使用Erlang,node.js只是关于并行IO,对于并行计算,它与Python或PHP一样糟糕 从中交叉发布
JavaScript中异步函数的用途与您所寻求的略有不同 记住JavaScript是单线程的——它一次只能做一件事。下面是一些传统的阻塞代码:
sys.puts("Before");
sleep(10);
sys.puts("After");
在真实的web应用程序中,sleep()
可能是一个耗时的数据库调用、网络请求(如等待来自用户web浏览器的数据)、帮助工具或文件访问
如果像上面那样使用阻塞调用,Node.js服务器在等待时将无法执行任何其他操作(如开始处理其他web请求)
PHP和许多其他web编程环境通过为每个请求创建完全独立的线程来处理此问题。js使用回调函数。您可以这样编写相同的代码:
sys.puts("Before");
setTimeout(function(){
sys.puts("After");
}, 10000);
在这里,创建一个函数并将其传递给setTimeout()
。它的代码还没有运行,但当它运行时,它将可以访问创建它的所有范围(所有变量)setTimeout()
获取对函数的引用,并计划在超时过期后触发事件
事件循环本质上是Node.js程序的待办事项列表(它们很常见——计算机上运行的所有GUI应用程序都可能使用事件循环!)
调用setTimeout()
后,当前函数将继续执行。它最终返回,调用它的函数返回,依此类推,直到程序返回到事件循环中。事件循环查看代码执行时是否发生了任何事情(例如,传入的请求),并调用代码中的相应函数。如果没有,它将等待直到某件事情发生(例如超时过期)
异步代码不允许您的代码同时做许多事情,当某些代码依赖外部事物继续时,它确实消除了阻塞
很少需要在Node.js程序中执行阻塞工作。如果这样做,您应该将该工作分离到一个单独的进程(甚至可以是另一个Node.js程序)中,或者编写一个可以自由使用线程的程序。您可以使用nextTick()不使用子进程来完成此工作 前几天我刚读到关于nextTick的解释。。。这是一本很棒的书 ---编辑:旧链接已失效。在StackOverflow上找到一个新的
如果我确实理解您的意图,那么您有两个函数(都以回调作为参数):
process.nextTick
:此函数可以堆叠,这意味着如果递归调用它,它将在事件循环的每个滴答中循环大量(process.maxTickDepth
)次
或
setImmediate
:此函数更接近于设置0超时(但发生在之前)
在大多数情况下,您应该更喜欢setImmediate。我假设您正在试验Nodejs,也假设您没有编写任何npm模块本身并将函数导出为异步函数,实际上您不会遇到这种情况,如果要在单线程环境中执行的函数或回调中执行任何阻塞操作,请尝试使用适当的节点模块(如fs)进行文件读取、网络请求请求和提供各种类型异步操作的异步模块,还要记住,您试图异步执行cpu消耗代码,这是一个坏主意,因为2HZ可以在不到微秒的时间内执行一百万行代码
nodejs的主要目的是解决您在问题中提出的问题,该问题由底层libuv处理以处理异步事件,我很欣赏使用set time out的答案,但您不知道需要等待多长时间,或者使用node worker也可以,但您最终会编写大量的锅炉板代码,因此,只需搜索满足您需要的npm模块。尝试基于事件循环模型(node.js的核心)回答这个问题
设置超时(doSomething,0)
。是,setTimeout
将向任务队列中添加任务。在0
秒之后,时间到了。事件循环检查任务队列并发现任务已完成,其回调函数doSomething
已准备好运行
上述过程是异步的
有一件事是肯定的