Javascript背后的异步性背后
请帮我理解这一点。
你有一个调用几个方法的函数:
function() {
methodA(function(){...});
methodB();
methodC();
}
从没有回调函数或匿名函数的语言中,我习惯了这样一个事实,那就是直到方法返回时,执行才会继续。
所以如果我用callback调用methodA,执行将不得不等待直到方法返回,这将不会是异步的,对吧?
例如,我可以将回调存储到某个对象,并让方法返回。 然后执行methodB和methodC。 当用户点击一个按钮,一些处理程序执行回调?
我得出结论认为,与java或python(不涉及多线程)相比,javascript没有任何异步...因为在java中,回调不会是闭包/匿名方法,而是带有“execute”方法的对象它会完全相同,只是稍微复杂一点...当然,这个JS事件系统特定于DOM
JavaScript中的回调不会隐式添加异步行为。 当调用回调函数时,它就像普通函数那样运行。 (其实,回调函数只是一个正常的功能...)
正因为如此,不可能确定何时该示例中的回调的执行将在关系运行到其它的方法(不同之处在于它不能之前运行methodA
被调用) -它可以被从调用methodA
或methodB
或从稍后的点击,或根本没有。 (然而,除非有一个例外-或的功能之一调用的其它功能中的一个-然后methodA
将之前运行methodB
这将在之前转弯运行methodC
;如果methodA
抛出异常然后既不methodB
也不methodC
将被调用)。
添加异步行为的是异步事件源,例如定时器事件或UI操作,如按钮单击。
但是,请务必记住,Javascript不具有或支持线程。 在可以触发新的异步事件之前,Javascript必须“停止”(执行必须从异步事件源调用的回调函数中返回)。 (异步事件按照适当的顺序排队,因此如果另一个回调执行时间过长,定时器事件不会“丢失”。)
这就是为什么while (true) {}
会使浏览器页面冻结并防止处理按钮事件处理程序。
快乐的编码。
示例(jsfiddle演示):
function invokeNow(callback) {
// nothing asynchronous going on here.
// the callback is invoked right now and the result is returned.
return callback()
}
alert(invokeNow(function () { return "Hello world!" }))
function doLater(callback) {
// setup an asynchronous event
setTimeout(callback, 1000)
return "It isn't 'later' yet!"
}
alert(doLater(function () {
alert("Later!")
// note that this is running in the callback from the previous
// timer event. if this code was below the outer alert then
// it wouldn't have allowed the first timer callback to have occurred
// until the blocking while was complete
alert(doLater(function () { alert("I still ran!") }))
var end = (+new Date) + 4000
while ((+new Date) < end) { /* wait */ }
alert("I am done waiting")
}))
警告:Firefox 4(4.0.1)和上述代码似乎存在问题。 虽然它的工作原理如图所示,但如果超时时间低于800毫秒左右,预期顺序与实际顺序不同。 我已经发布SO:在Firefox 4中同步运行(“buggy”)的异步计时器事件? 所以希望会有一些解决方案。 该行为在Firefox 3,IE 9和Chrome 11中按预期工作。
function main() {
methodA(function callback(){...});
methodB();
methodC();
}
假设回调没有立即执行。
执行顺序:
除非您使用setInterval
, setTimeout
或使用onload
或使用onload
向服务器发出请求,否则JavaScript是顺序的。 不确定是否有其他情况。
如果你有类似的东西:
function methodA(fn){
...
fn();
}
然后,当您调用methodA(function(){...})
时,将调用回调methodA(function(){...})
上一篇: What stands behind asynchronicity in Javascript
下一篇: What is the difference between null and undefined in JavaScript?