gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 23:10:01 25 4
gpt4 key购买 nike

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

让我们考虑 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 代码片段。我一般问 - 是什么让程序在遇到回调函数时继续执行的技巧。语法是什么这使得回调概念成为非阻塞概念?

提前致谢!

最佳答案

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

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. 使用另一个异步函数,例如 setTimeout或网络 worker 来执行你的逻辑。

  2. 用 C 编写。

C语言函数(如setTimeout)是如何实现异步执行的?这一切都与事件循环(或大部分)有关。

事件循环

在网络浏览器中有一段用于联网的代码。最初,网络代码只能下载一件事:HTML 页面本身。当马赛克发明 <img>标记网络代码演变为下载多个资源。然后网景实现了progressive rendering对于图像,他们必须使网络代码异步,以便他们可以在加载所有图像之前绘制页面并逐步和单独地更新每个图像。这就是事件循环的由来。

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

select() C 中的函数允许您在单个线程中等待多个 I/O 操作,而无需产生额外的线程。 select()看起来像:

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

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

javascript 解释器保存您的回调,然后调用 select()功能。当select()返回解释器确定哪个回调与哪个 I/O channel 相关联,然后调用它。

方便,select()还允许您指定 timeout值(value)。通过精心管理timeout传递给 select()您可以在将来的某个时间调用回调。这就是 setTimeoutsetInterval被实现。解释器保留所有超时的列表并计算它需要传递的内容为timeout。至select() .那么当select()除了查明是否有任何由于 I/O 操作而需要调用的回调之外,解释器还会检查任何需要调用的过期超时。

所以 select()仅此一项就涵盖了实现异步功能所需的几乎所有功能。但是现代浏览器也有网络 worker 。在 web worker 的情况下,浏览器会产生线程来异步执行 javascript 代码。要与主线程通信,worker 仍必须与事件循环(select() 函数)交互。

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


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

有关更多信息,另请参阅:

关于javascript - 我知道回调函数是异步运行的,但是为什么呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29883525/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com