是什么决定哪些Javascript函数正在阻塞与非阻塞?


27

几年来,我一直在做基于Web的Javascript(香草JS,jQuery,Backbone等),最近我正在与Node.js做一些工作。我花了一段时间才能摆脱“非阻塞”编程的束缚,但是我现在已经习惯于将回调用于IO操作等等。

我了解Javascript本质上是单线程的。我了解节点“事件队列”的概念。我不明白是什么决定了单个javascript操作是“阻止”还是“非阻止”。我如何知道我可以依靠哪些操作来同步生成输出供我在以后的代码中使用,以及我需要将哪些回调传递给我以便在初始操作完成后处理输出?在某个地方是否存在异步/非阻塞的Javascript函数列表,以及同步/阻塞的Javascript函数列表?是什么阻止我的Javascript应用成为一种激烈的竞争状况?

我知道需要很长时间的操作,例如Node中的IO操作和Web上的AJAX操作,要求它们是异步的并因此使用回调-但是谁在确定什么才是“长时间”?这些操作中是否有某种触发器可以将其从正常的“事件队列”中删除?如果不是,那么它们与简单的操作(如为变量赋值或遍历数组)之类的简单操作有何不同?似乎我们可以依靠它们以同步方式完成操作?

也许我什至没有正确地考虑这一点-希望有人可以让我直率。谢谢!


这是一些我发现,是真的很有用,即使你的回答你的问题是,你必须检查的文件,以找出是否方法是异步。
Anastasios Andronidis 2014年

Answers:


13

通常,在一段时间内执行联网或使用计时器执行操作的任何功能都是异步的。

如果该函数接受了回调,则可以查看该回调的用途,并且通常可以看出该回调是否异步。如果该函数不提供回调,则它无法传递异步结果,因此它可能不是异步的。

没有铁定的说法可以肯定。它必须在文档中说明某个功能,或者从接口的工作方式中显而易见。

异步操作与同步操作在本质上有所不同,因为异步操作的概念是设置操作,开始操作,然后在以后通知操作的进度,完成或错误。迭代数组是一个同步操作。它没有这些问题。该代码只是同步运行。发出ajax调用包括注册用于状态通知的回调,然后启动ajax调用,然后继续运行其他javascript,然后一段时间后,该回调将在ajax调用上进行状态更改(例如完成)。


1
另外需要注意的是,某些Javascript函数根据其参数同时具有阻塞性和非阻塞性。例如,XMLHttpRequest.open具有一个布尔async参数,该参数控制以后对的调用send是否异步。
布赖恩

我只是觉得这个答案没有用,并且没有得到一般性的解释。
Mehdi Raash

@MehdiRaash-答案是您可以从文档或界面中找出答案。没有别的办法了。这就是这个意思。不知道您还期望什么。没有魔术的答案。
jfriend00

6

据我了解,您不是在问应该使异步什么而是在问一个函数是否异步。

您检查文档。说真的-这就是它的目的。您不会仅仅基于函数名称或上下文来猜测函数的作用。如果不确定并可以访问其源代码,请进行检查。

这是唯一完全可靠的方法。

现在进行猜测。

  • 如果它接受回调或返回承诺,则可能是异步的(我见过该规则的异常)
  • 通常,node.js中与I / O相关的所有内容,以及JavaScript中与I / O相关的所有内容,都是异步完成的(我也看到了该规则的例外情况)

4

由于JavaScript是单线程的,因此所有处理块均会发生以下情况之一

1)当前执行请求外部服务,例如I / O或网络请求或Webworker请求

2)将函数调用置于计时器上,以便稍后执行

没有阻止/非阻止功能列表。您应该检查文档。

如果多个外部服务在javascript线程上锁定并尝试同时访问它,则您的应用可能会遇到竞争状况。现代浏览器和V8引擎可以处理此问题,但是如果您使用phonegap并为移动设备编写javascript应用程序,则可能会遇到这种竞争情况。没有支持来解决这些比赛条件。

通常,除非有回调,否则假定代码块。即使有回调,也并不意味着它不会阻塞。


-1

我也是node.js(和JavaScript的新手)的新手,而且我不习惯使用太多异步代码。我只想指出,在nodejs.org的“阻止与非阻止概述”中指出:

Node.js标准库中的所有I / O方法都提供非阻塞的异步版本,并接受回调函数。某些方法还具有阻塞的对应项,它们的名称以Sync结尾。


1
请问该如何解决这个问题?请参阅如何回答
蚊蚋
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.