默认情况下是Javascript同步(阻塞)还是异步(非阻塞)

时间:2013-05-13 13:56:27

标签: javascript node.js asynchronous callback asynccallback

我正在尝试掌握Javascript异步函数和回调。

我坚持回调函数的概念,我在一些地方阅读:它们用于顺序执行代码(主要是在jquery的上下文中,例如animate)和一些特别在Nodejs上下文的地方;它们用于并行执行异步并避免阻塞代码。

因此,本主题的一些专家可以阐明这一点,并在我的脑海中清除这个模糊(例子??)。  所以我可以考虑使用回调函数

还是仅取决于您在代码中调用/放置回调函数的位置?

谢谢,

P.S:我担心这个问题会接近主观,但我仍然可以期待具体的答案(也许是一些例子)

编辑:实际上这是来自互联网的例子让我很暧昧:

function do_a(){
  // simulate a time consuming function
  setTimeout( function(){
    console.log( '`do_a`: this takes longer than `do_b`' );
  }, 1000 );
}

function do_b(){
  console.log( '`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a`' );
}

do_a();
do_b();

结果

`do_b`: this is supposed to come out after `do_a` but it comes out before `do_a`
`do_a`: this takes longer than `do_b`

当JS是顺序的时候,根据我的理解,do_b应该总是在do_a之后。

3 个答案:

答案 0 :(得分:25)

JavaScript的核心很大程度上是同步的,因为函数在完成之前完全完成了它们的任务。在AJAX出现之前,实际上只有setTimeout和setInterval提供了异步行为。

然而,很容易忘记事件处理程序是有效的异步代码。附加处理程序不会调用处理程序代码,并且在将来某个不可知的时间之前不会执行该代码。

然后是AJAX,它调用了服务器。这些调用可以配置为同步,但开发人员通常首选异步调用并使用回调方法来实现它们。

然后,我们看到了JS库和工具包的激增。它们努力使不同浏览器的实现同质化,并建立在异步代码的回调方法之上。您还开始看到更多的同步回调,例如数组迭代或CSS查询结果处理。

现在,我们看到混合中的Deferreds和Promises。这些对象表示长时间运行的操作的值,并提供用于在到达时处理该值的API。

NodeJS倾向于采用异步方法处理许多事情;那是真的。然而,这更多是他们的设计决策,而不是JS的任何固有的异步性质。

答案 1 :(得分:12)

Javascript始终是一种同步(阻塞)单线程语言,但我们可以通过编程使Javascript行为异步。

同步代码:

console.log('a');
console.log('b');

异步代码:

console.log('a');
setTimeout(function() {
    console.log('b');
}, 1000);
setTimeout(function() {
    console.log('c');
}, 1000);
setTimeout(function() {
    console.log('d');
}, 1000);
console.log('e');

输出:a e b c d

答案 2 :(得分:3)

在节点长时间运行的进程中,使用process.nextTick()对函数/回调进行排队。这通常在节点的API中完成,除非您的编程(在api之外)具有阻塞或长时间运行的代码,否则它不会对您产生太大影响。下面的链接应该更好地解释它。

howtonode process.nextTick()

jQuery AJAX也会进行回调,例如它的编码不会在转移到下一个代码块之前等待服务器响应。它只记得服务器响应时运行的功能。这基于浏览器公开的XMLHTTPRequest对象。 XHR对象将记住响应返回时要回调的函数。

一旦调用堆栈为空(下一个可用空闲滴答),

setTimeout(fn, 0) javascript将运行一个函数,可用于创建异步函数。setTimeout(fn, 0) question on stackoverflow

将javascript的异步能力与其作为javascript本身编程的环境一样多。除非使用一些API /脚本,否则只需使用大量函数调用和回调就不会获得任何魔力。

Jquery Deferred Object是jQuery异步功能的另一个很好的链接。谷歌搜索可能会找到有关jQuery Deferred如何工作的信息,以获得更多洞察力。