Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/google-maps/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在node.js中创建非阻塞异步函数?_Node.js - Fatal编程技术网

如何在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
已准备好运行

上述过程是异步的

有一件事是肯定的