2013-05-13 124 views
17

我想抓住Javascript异步函数和回调。默认为Javascript同步(阻止)或异步(非阻塞)

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

因此,在这个主题的一些专家请澄清这一点,并清除我脑海中的这个模糊(例子??)。 所以我可以让我的脑海回调函数的用法

或者说是完全取决于你在哪里调用/放置一个回调函数在代码的地方吗? 。

感谢,

PS:我很害怕,这个问题将是接近主观的,但我依然可以期待这个具体的答案(也许是一些例子)

编辑:其实这是例如,从互联网这让我ambigous:

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之后出现。

+6

JavaScript是JavaScript的;它取决于上下文,用法,引擎等。 – 2013-05-13 14:00:00

+0

你能否提供一些你不确定它是否阻塞与非阻塞的示例代码? – Matt 2013-05-13 14:06:11

+0

JavaScript通常是同步的,但根据定义,setTimeout是异步的。这里有一个很好的入门知识:https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout – 2013-05-13 14:25:02

回答

2

在节点长时间运行的进程中,使用process.nextTick()排队函数/回调。这通常是在节点的API中完成的,除非你的编程(在api之外)有阻塞的东西或长时间运行的代码,那么它对你没有太大的影响。下面的链接应该更好地解释它,然后我可以。

howtonode process.nextTick()

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

setTimeout(fn, 0) javascript会在调用堆栈为空时运行一个函数(下一个可用的空闲tick),它可以用来创建类似异步的特性。 setTimeout(fn, 0) question on stackoverflow

为了总结javascript的异步能力与他们在javascript中编程的环境同样重要。除非您使用一些API /脚本,否则您不会通过使用大量函数调用和回调来获得任何魔力。

Jquery Deferred Object是jQuery的异步功能的另一个好链接。 Google搜索可能会找到关于jQuery Deferred如何工作的信息以获取更多信息。

22

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

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

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

然后,我们看到了JS库和工具包的激增。这些努力均匀化不同浏览器的事物实现,并建立在异步代码的回调方法上。你也开始看到像数组迭代或CSS查询结果处理这样的更多同步回调。

现在,我们看到了组合中的延迟和承诺。这些对象表示长时间运行的操作的值,并提供用于处理该值的API。

NodeJS倾向于一种异步的方法来处理许多事情;这是事实。然而,这更像是一个设计决定,而不是JS的任何固有的异步性质。

10

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

+0

在这种情况下阻塞是什么意思? – 2016-03-14 18:38:09