什么使JavaScript函数异步?

时间:2018-04-26 19:23:53

标签: javascript node.js asynchronous

我的目标是了解某些使它们异步的JavaScript函数到底是什么。你可以有这样的功能:

function someRandomFunction () {
  for (let i of everything) {
    iterator++
    something = true
    hello = that + whatever
  }
}

这个函数没什么是异步的。它做了很多东西,但它很快就完成了。

然后采用这样的Node.js函数:

fs.readFile('path/to/file', (err, data) => {
  // do something
})

此函数声明为异步。但为什么呢?它背后的原因是什么?

是否因为读取文件需要一定的时间才能完成,因此它是异步的?为什么在循环某些变量并进行某些计算时异步是不同步的?

4 个答案:

答案 0 :(得分:4)

异步的“想法”意味着“我们已经放弃了对其他操作代码的控制,我们不知道其他代码何时会让我们再次运行”。

因此,在您的底部示例中,您可以控制节点的文件系统操作以读取文件。我们不知道该文件有多大,因此无法预测完成所需的时间。所以JavaScript允许我们提供一个“回调”,当异步操作完成时会被触发。执行回调时,控制权返回给我们的代码。

顶级示例是同步的,因为您的代码保持对操作的控制,Javascript本质上是同步执行代码。

答案 1 :(得分:1)

一个函数是显式同步或异步的;没有“一定的时间”自动使其异步。

要记住Node的重要一点是它是“异步I / O”,这意味着没有任何输入/输出到进程的任何东西都不会异步。您通常会看到文件读/写,数据库调用以及需要网络调用的任何内容。

答案 2 :(得分:1)

就JavaScript而言,同步和异步函数之间的区别在于执行代码的位置和时间。同步功能在当前调用堆栈中一个接一个地立即执行。异步函数被传递给事件循环,并且在当前调用堆栈完成执行后返回值。

请注意,由于JS只在单个进程线程上执行,因此JavaScript中的任何内容都不是真正异步的

答案 3 :(得分:1)

这是一个基本但基本的问题。将函数传递给另一个函数并不会使代码自动异步。所有关于使用另一段代码(大部分来自未知来源)的工作都可能,但可能与操作系统的IO机制无关。换句话说,通过将任务交给可能在单独线程上运行的已知或未知资源,您可以从当前正在执行的JS上下文领域发出一些事情。

正如我所说,这可能是一个IO操作或数据库访问,你不知道

  • 正在运行什么代码
  • 正在运行的线程
  • 需要多长时间
  • 是否会成功

在幕后,这些外星人代码最终触发事件队列,通过驱动程序调用回调函数。在像Haskell这样的纯函数式语言中,这些活动严格地远离上下文,必须由monadic类型函数处理。在JS中,这基本上是通过回调,promises或async-awiat机制的异步工作流来完成的。

一旦将任务分发给外部世界,就无法干扰您的同步代码。