我试图研究应该如何编写完全异步的函数.经过大量文档的大量工作后,我仍然不清楚.
如何为Node编写异步函数?我该如何正确实现错误事件处理?
问我问题的另一种方法是:我应该如何解释以下功能?
var async_function = function(val, callback){
process.nextTick(function(){
callback(val);
});
};
Run Code Online (Sandbox Code Playgroud)
另外,我发现SO上的这个问题("如何在node.js中创建非阻塞异步函数?")很有趣.我觉得它还没有得到回答.
如何进行简单的非块Javascript函数调用?例如:
//begin the program
console.log('begin');
nonBlockingIncrement(10000000);
console.log('do more stuff');
//define the slow function; this would normally be a server call
function nonBlockingIncrement(n){
var i=0;
while(i<n){
i++;
}
console.log('0 incremented to '+i);
}
Run Code Online (Sandbox Code Playgroud)
输出
"beginPage"
"0 incremented to 10000000"
"do more stuff"
Run Code Online (Sandbox Code Playgroud)
如何形成这个简单的循环以异步执行并通过回调函数输出结果?这个想法是不阻止"做更多的东西":
"beginPage"
"do more stuff"
"0 incremented to 10000000"
Run Code Online (Sandbox Code Playgroud)
我已经尝试过关于回调和延续的教程,但它们似乎都依赖于外部库或函数.他们都没有在真空中回答这个问题:如何编写Javascript代码是非阻塞的??
在询问之前,我非常努力地寻找这个答案; 请不要以为我没看.我发现的一切都是Node.js特定的([1],[2],[3],[4],[5])或其他特定于其他函数或库([6],[7],[8],[9],[10],[11]),特别是JQuery和setTimeout()
.请帮我用Javascript编写非阻塞代码,而不是Javascript和Node等Javascript编写的工具. 请在将其标记为重复之前重新阅读该问题.
以下示例在Node.js书中给出:
var open = false;
setTimeout(function() {
open = true
}, 1000)
while (!open) {
console.log('wait');
}
console.log('open sesame');
Run Code Online (Sandbox Code Playgroud)
作者解释说明while循环阻止执行的原因:
Node永远不会执行超时回调,因为事件循环停留在第7行的while循环中,永远不会让它有机会处理超时事件!
但是,作者没有解释为什么会在事件循环的上下文中发生这种情况或者真正发生在幕后的事情.
有人可以详细说明吗?节点为什么会卡住?如何更改上面的代码,同时保留while
控制结构,以便不阻止事件循环,并且代码将按照人们可能合理预期的方式运行; 等待将在setTimeout
火灾前记录仅1秒,然后在记录"打开芝麻"后退出该过程.
关于IO和事件循环和回调这个问题的答案等通用解释并没有真正帮助我理解这一点.我希望直接引用上述代码的答案会有所帮助.
我很难理解它究竟是怎么process.nextTick
回事.我以为我理解了,但我似乎无法复制我觉得这应该有效:
var handler = function(req, res) {
res.writeHead(200, {'Content-type' : 'text/html'});
foo(function() {
console.log("bar");
});
console.log("received");
res.end("Hello, world!");
}
function foo(callback) {
var i = 0;
while(i<1000000000) i++;
process.nextTick(callback);
}
require('http').createServer(handler).listen(3000);
Run Code Online (Sandbox Code Playgroud)
虽然foo
是循环的,我会在几个请求发送,假设handler
将排队几次身后foo
有callback
只在被排队foo
完成.
如果我对这是如何工作正确的,我认为结果将如下所示:
received
received
received
received
bar
bar
bar
bar
Run Code Online (Sandbox Code Playgroud)
但它没有,它只是顺序的:
received
bar
received
bar
received
bar
received
bar
Run Code Online (Sandbox Code Playgroud)
我看到它foo
在执行之前正在返回,callback
这是预期的,但似乎callback
是NEXT在队列中,而不是在队列的末尾,在所有请求进入后面.这是否有效?也许我只是不明白节点中的事件队列是如何工作的.请不要指我在这里.谢谢.
我有大量的数据处理操作,每个10-12个模拟请求都需要完成。我已经读到,对于更高级别的并发,Node.js是一个很好的平台,它通过具有非阻塞事件循环来实现。
我所知道的是,有像查询数据库的东西,我可以激活一个事件到一个单独的进程(如mongod
,mysqld
),然后有一个回调,这将处理来自该进程的结果。很公平。
但是,如果我想在回调中进行大量计算,该怎么办?在该回调中的代码完全执行之前,它不会阻止其他请求。例如,我想处理高分辨率图像,而我拥有的代码在Javascript本身(no separate
用于图像处理的过程)中。
我想到的实现方式就像
get_image_from_db(image_id, callback(imageBitMap) {
heavy_operation(imageBitMap); // Can take 5 seconds.
});
Run Code Online (Sandbox Code Playgroud)
heavy_operation
在那5秒钟内,该节点将停止接收任何请求吗?还是我在思考执行此类任务的错误方法。请指导,我是JS新手。
更新
或者就像我可以处理部分图像并使事件循环返回以接受其他回调并返回到处理该部分图像一样。(类似于对事件进行优先级排序)。