DCD*_*CDC 12 javascript asynchronous callback node.js
语法的哪一部分提供了此函数应该在其他线程中运行并且是非阻塞的信息?
让我们考虑node.js中的简单异步I/O.
var fs = require('fs');
var path = process.argv[2];
fs.readFile(path, 'utf8', function(err,data) {
var lines = data.split('\n');
console.log(lines.length-1);
});
Run Code Online (Sandbox Code Playgroud)
究竟是什么让它在背景中发生?任何人都可以准确地解释它或粘贴一些好资源的链接?我看到的每个地方都有关于回调是什么的大量信息,但没有人解释为什么它实际上是这样的.
这不是关于node.js的具体问题,而是关于每种编程语言中回调的一般概念.
编辑:
可能我提供的例子并不是最好的.所以我们不要考虑这个node.js代码片段.我一般都在问 - 当遇到回调函数时,程序是如何继续执行的.什么是语法使回调概念成为非阻塞概念?
提前致谢!
sle*_*man 20
有没有在告诉你,你的回调是异步执行的语法.回调可以是异步的,例如:
setTimeout(function(){
console.log("this is async");
}, 100);
Run Code Online (Sandbox Code Playgroud)
或者它可以是同步的,例如:
an_array.forEach(function(x){
console.log("this is sync");
});
Run Code Online (Sandbox Code Playgroud)
那么,你怎么知道一个函数是同步还是异步调用回调?唯一可靠的方法是阅读文档.
您还可以编写测试以查明文档是否不可用:
var t = "this is async";
some_function(function(){
t = "this is sync";
});
console.log(t);
Run Code Online (Sandbox Code Playgroud)
Javascript本身没有任何使函数异步的功能.如果要编写异步函数,您有两个选择:
使用其他异步函数(如setTimeoutweb worker)来执行逻辑.
用C写.
至于C编码函数(如setTimeout)如何实现异步执行?这一切都与事件循环(或大部分)有关.
在Web浏览器中,有一段用于网络的代码.最初,网络代码只能下载一件事:HTML页面本身.当Mosiac发明<img>标签时,网络代码逐渐演变为下载多个资源.然后Netscape实现了图像的渐进式渲染,他们必须使网络代码异步,以便他们可以在加载所有图像之前绘制页面,并逐步和单独地更新每个图像.这是事件循环的起源.
在浏览器的核心,有一个从异步网络代码演变而来的事件循环.因此,它使用I/O原语作为其核心并不奇怪:( select()或类似的东西,如poll,epoll等取决于操作系统).
select()C中的函数允许您在单个线程中等待多个I/O操作,而无需生成其他线程.select()看起来像:
select (max, readlist, writelist, errlist, timeout)
Run Code Online (Sandbox Code Playgroud)
要让它等待I/O(来自套接字或磁盘),您需要将文件描述符添加到readlist它,并且当您的任何I/O通道上有可用数据时它将返回.一旦它返回,您可以继续处理数据.
javascript解释器保存您的回调,然后调用该select()函数.当select()返回解释附图哪个回调关联与I/O信道,然后调用它.
方便的是,select()还允许您指定timeout值.通过仔细管理timeout传递给select()您可以导致在将来的某个时间调用回调.这是怎么setTimeout和setInterval实现.该解释使所有超时的名单,并计算它需要通过为timeout到select().然后当select()返回时,除了发现是否存在由于I/O操作而需要调用的任何回调之外,解释器还检查需要调用的任何过期超时.
所以select()单独涵盖了实现异步功能所需的几乎所有功能.但现代浏览器也有网络工作者.对于Web worker,浏览器会生成线程以异步方式执行javascript代码.要与主线程进行通信,工作人员仍必须与事件循环(select()函数)进行交互.
Node.js在处理文件/磁盘I/O时也会生成线程.当I/O操作完成时,它与主事件循环进行通信以使适当的回调执行.
希望这能回答你的问题.我一直想写这个答案但是之前很忙.如果您想了解有关CI中非阻塞I/O编程的更多信息,建议您阅读以下内容:http://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html
| 归档时间: |
|
| 查看次数: |
2427 次 |
| 最近记录: |