我知道回调函数异步运行,但是为什么呢?

DC

语法的哪一部分提供了该函数应在其他线程中运行并且是非阻塞的信息?

让我们考虑一下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);
  });

是什么使它在后台发生的呢?任何人都可以准确地解释它,还是可以粘贴指向一些良好资源的链接?我到处看的地方都有很多关于什么是回调的信息,但是没有人解释为什么它实际上如此工作。

这不是关于node.js的特定问题,而是关于每种编程语言中回调的一般概念。

编辑:

我提供的示例可能在这里不是最好的。因此,我们不要考虑此node.js代码段。我一般来说是在问-遇到回调函数时,使程序不断执行的诀窍是什么?使回调概念成为非阻塞性语法的语法是什么?

提前致谢!

slebetman

没有在告诉你,你的回调是异步执行的语法。回调可以是异步的,例如:

setTimeout(function(){
    console.log("this is async");
}, 100);

或者可以是同步的,例如:

an_array.forEach(function(x){
    console.log("this is sync");
});

因此,您如何知道某个函数将同步还是异步调用回调?唯一可靠的方法是阅读文档。

您还可以编写测试来确定文档是否不可用:

var t = "this is async";
some_function(function(){
    t = "this is sync";
});

console.log(t);

异步代码如何工作

就其本身而言,JavaScript不具有使功能异步的任何功能。如果要编写异步函数,则有两个选择:

  1. 使用另一个异步函数,例如setTimeoutWeb或Web worker来执行您的逻辑。

  2. 用C写

至于C编码函数(例如setTimeout)如何实现异步执行?这一切都与事件循环有关(或大部分与事件循环有关)。

事件循环

Web浏览器内部有这段代码用于网络连接。最初,网络代码只能下载一件事:HTML页面本身。当Mosaic发明<img>标签时,网络代码演变为下载多种资源。然后,Netscape实施了图像的渐进式渲染,他们必须使联网代码异步,以便他们可以在加载所有图像之前绘制页面,并逐步和逐个更新每个图像。这是事件循环的起源。

在浏览器的中心,有一个从异步网络代码演变而来的事件循环。因此,它使用I / O原语作为核心也就不足为奇了:(select()或类似的东西,例如poll,epoll等,取决于OS)。

select()C语言中函数使您可以在单个线程中等待多个I / O操作,而无需产生其他线程。select()看起来像:

select (max, readlist, writelist, errlist, timeout)

要让它等待I / O(来自套接字或磁盘),您可以将文件描述符添加到中readlist,当任何I / O通道上有可用数据时,它将返回。一旦返回,您就可以继续处理数据。

javascript解释器保存您的回调,然后调用该select()函数。select()返回时,解释器找出哪个回调与哪个I / O通道相关联,然后调用它。

方便地,select()还允许您指定一个timeout值。通过仔细管理timeout传递给select()您的内容,可以导致将来某个时候调用回调。这是怎么setTimeoutsetInterval实现。解释器会保留所有超时的列表,并计算需要传递的timeout时间select()然后,当select()返回时,除了查找是否由于I / O操作需要调用任何回调外,解释器还会检查是否需要调用任何过期的超时。

因此,select()仅涉及实现异步功能所需的几乎所有功能。但是现代浏览器也有网络工作者。对于网络工作者,浏览器会生成线程以异步执行javascript代码。为了与主线程通信,工作人员仍必须与事件循环(select()函数)进行交互

在处理文件/磁盘I / O时,Node.js也产生线程。I / O操作完成后,它将与主事件循环通信回去,以使适当的回调得以执行。


希望这能回答您的问题。我一直想写这个答案,但是以前很忙。如果您想了解有关CI中非阻塞I / O编程的更多信息,建议您阅读以下内容:http : //www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html

有关更多信息,请参见:

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

为什么我的回调不是函数?

来自分类Dev

在异步中运行回调函数

来自分类Dev

为什么在异步函数中未执行带有回调的函数?

来自分类Dev

boost :: asio,为什么我的套接字在调用async_receive_from后立即运行回调函数?

来自分类Dev

那么为什么不保持回调的顺序呢?

来自分类Dev

Node.js-为什么我的某些回调不异步执行?

来自分类Dev

调用函数不明确,但是为什么呢?

来自分类Dev

我期望无限循环,但是为什么呢?

来自分类Dev

为什么我的WCF回调超时?

来自分类Dev

使用异步运行递归函数时回调错误

来自分类Dev

为什么我的小蜘蛛在我的项目解析函数中不遵循Request回调?

来自分类Dev

为什么这段代码中没有运行回调函数?

来自分类Dev

静态类是否创建实例?msdn说我没有,但是为什么要构造函数呢?

来自分类Dev

我不知道为什么,但是当我运行以下代码时,它返回9作为质数

来自分类Dev

为什么JSHint会警告我有关在回调函数中使用'this'的信息?

来自分类Dev

为什么我不能直接将console.log()设置为回调函数

来自分类Dev

当我尝试caputre [this]时,用于回调函数的lambda表达式失败,为什么?

来自分类Dev

为什么我的回调函数接收到不正确的参数值?

来自分类Dev

为什么我的回调函数接收到不正确的参数值?

来自分类Dev

为什么我的回调函数收到未定义的参数值?

来自分类Dev

systemd target multi-user.target失败,但是如何知道为什么呢?

来自分类Dev

如果函数是值,为什么回调函数不能是变量?

来自分类Dev

几次运行函数,但是为什么我只看到输出返回一次?

来自分类Dev

运行量角器/ webdriver的异步回调/承诺不知道

来自分类Dev

为什么我的异步代码没有运行异步?

来自分类Dev

所有的JavaScript回调都是异步的吗?如果没有,我怎么知道是哪个?

来自分类Dev

我不知道为什么我的代码是错误的?那是什么错呢?

来自分类Dev

模块被禁用-但是为什么呢?

来自分类Dev

Ruby:NoMethodError,但是为什么呢?

Related 相关文章

  1. 1

    为什么我的回调不是函数?

  2. 2

    在异步中运行回调函数

  3. 3

    为什么在异步函数中未执行带有回调的函数?

  4. 4

    boost :: asio,为什么我的套接字在调用async_receive_from后立即运行回调函数?

  5. 5

    那么为什么不保持回调的顺序呢?

  6. 6

    Node.js-为什么我的某些回调不异步执行?

  7. 7

    调用函数不明确,但是为什么呢?

  8. 8

    我期望无限循环,但是为什么呢?

  9. 9

    为什么我的WCF回调超时?

  10. 10

    使用异步运行递归函数时回调错误

  11. 11

    为什么我的小蜘蛛在我的项目解析函数中不遵循Request回调?

  12. 12

    为什么这段代码中没有运行回调函数?

  13. 13

    静态类是否创建实例?msdn说我没有,但是为什么要构造函数呢?

  14. 14

    我不知道为什么,但是当我运行以下代码时,它返回9作为质数

  15. 15

    为什么JSHint会警告我有关在回调函数中使用'this'的信息?

  16. 16

    为什么我不能直接将console.log()设置为回调函数

  17. 17

    当我尝试caputre [this]时,用于回调函数的lambda表达式失败,为什么?

  18. 18

    为什么我的回调函数接收到不正确的参数值?

  19. 19

    为什么我的回调函数接收到不正确的参数值?

  20. 20

    为什么我的回调函数收到未定义的参数值?

  21. 21

    systemd target multi-user.target失败,但是如何知道为什么呢?

  22. 22

    如果函数是值,为什么回调函数不能是变量?

  23. 23

    几次运行函数,但是为什么我只看到输出返回一次?

  24. 24

    运行量角器/ webdriver的异步回调/承诺不知道

  25. 25

    为什么我的异步代码没有运行异步?

  26. 26

    所有的JavaScript回调都是异步的吗?如果没有,我怎么知道是哪个?

  27. 27

    我不知道为什么我的代码是错误的?那是什么错呢?

  28. 28

    模块被禁用-但是为什么呢?

  29. 29

    Ruby:NoMethodError,但是为什么呢?

热门标签

归档