Javascript 异步性的背后是什么 - 事件驱动系统

发布于 2024-11-08 21:16:37 字数 468 浏览 0 评论 0原文

请帮助我理解这一点。

您有一个调用一些方法的函数:

function() {
   methodA(function(){...});
   methodB();
   methodC();
}

对于没有回调或匿名函数的语言,我已经习惯了这样一个事实:在方法返回之前,执行不会继续。

因此,如果我使用回调调用 methodA,则执行必须等到该方法返回,这不是异步的,对吧?

例如,我可以将回调存储到某个对象并让 methodA 返回。然后执行方法B和方法C。当用户单击按钮时,某些处理程序会执行回调?

我得出的结论是,与 java 或 python 相比,javascript 没有什么异步性(不涉及多线程)....因为在 java 中回调不会是闭包/匿名方法,而是具有“execute”方法的对象它会是完全一样的,只是稍微复杂一点......当然有这个专门针对 DOM 的 JS 事件系统

please help me understand this.

You have a function that calls a few methods:

function() {
   methodA(function(){...});
   methodB();
   methodC();
}

From languages that don't have callbacks or anonymous functions I got used to the fact, that the execution doesn't go on until a method returns.

So that if I called methodA with the callback, the execution would have to wait until the method returns which wouldn't be asynchronous, right ?

So that, for instance, I can store the callback to some object and have the methodA return. Then methodB and methodC are executed. And when user clicks a button, some handler executes the callback ?

I've come to conclusion that there is nothing asynchronous about javascript in comparison with java or python (not regarding multithreading).... because in java the callback wouldn't be closure/anonymous method, but an object with "execute" method and it would be exactly the same, just a little bit more complicated ... Of course there is this JS event system specific for DOM

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

吃不饱 2024-11-15 21:16:37

JavaScript 中的回调不会隐式添加异步行为。当调用回调函数时,它会立即运行,就像普通函数一样。 (实际上,回调函数只是一个普通的函数...)

因此,不可能确定示例中回调的执行将在何时运行与其他方法的关系(除了它不能在调用 methodA 之前运行)——它可以从 methodAmethodB 或稍后点击,或者根本不点击。 (但是,除非出现异常,或者其中一个函数调用其他函数之一,否则 methodA 将在 methodB 之前运行,而 methodB 又会在 methodB 之前运行code>methodC;如果 methodA 抛出异常,则 methodBmethodC 都不会被调用)。

添加异步行为的是异步事件源,例如计时器事件或 UI 操作(例如按钮单击)。

然而,请务必记住,Javascript 没有也不支持线程。在触发新的异步事件之前,Javascript 必须“停止”(执行必须从异步事件源调用的回调函数返回)。 (异步事件[酌情]排队,因此如果另一个回调执行时间太长,计时器事件不会“丢失”。)

这就是为什么 while (true) {} 将使浏览器页面冻结并阻止处理按钮事件处理程序。

快乐编码。


示例案例(jsfiddle demo):

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.0)似乎存在问题。 1) 和上面的代码。虽然其工作原理如演示的那样,但如果超时低于约 800 毫秒,则预期顺序与实际顺序不同。我已经发布了 SO:异步计时器事件同步运行(“buggy” )在 Firefox 4 中? 所以希望会有一些解决方案。该行为在 Firefox 3、IE 9 和 Chrome 11 中按预期工作。

Callbacks in JavaScript do not implicitly add asynchronous behavior. When a callback function is invoked, it runs right then, just as a normal function. (Actually, a callback function is just a normal function...)

Because of this, it is impossible to determine when the execution of the callback in the example will run in relationship to the other methods (except that it can't run before methodA is invoked) -- it could be called from methodA or methodB or from a click later, or not at all. (However, unless there is an exception -- or one of the functions invokes one of the other functions -- then methodA will run before methodB which will in turn run before methodC; if methodA threw an exception then neither methodB nor methodC would be invoked).

What does add asynchronous behavior is an asynchronous event source, such as a timer event or UI action such as a button click.

However, it is important to keep in mind that Javascript does not have or support threading. The Javascript must "stop" (execution must return from the callback function invoked from an asynchronous event source) before a new asynchronous event can be triggered. (Asynchronous events are queued [as appropriate] so a timer event won't be "lost" if another callback takes too long to execute.)

This is why while (true) {} will make a browser page freeze and prevent button event handlers from being processed.

Happy coding.


Example cases (jsfiddle demo):

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")
}))

Warning: There seems to be an issue with Firefox 4 (4.0.1) and the code above. While it works as demonstrated, the expected order differs from the actual order if the timeout is below about 800ms. I have posted SO: Asynchronous timer event running synchronously (“buggy”) in Firefox 4? so hopefully there will be some resolution. The behavior works as expected in Firefox 3, IE 9, and Chrome 11.

老子叫无熙 2024-11-15 21:16:37
function main() {
   methodA(function callback(){...});
   methodB();
   methodC();
}

假设回调没有立即执行。

执行顺序:

  • methodA
  • methodB
  • methodC
  • ...其他事情直到栈空
  • 回调
function main() {
   methodA(function callback(){...});
   methodB();
   methodC();
}

Assuming that callback is not immediately executed.

Execution order:

  • methodA
  • methodB
  • methodC
  • ... other things until the stack is empty
  • callback
我的鱼塘能养鲲 2024-11-15 21:16:37

Javascript 是顺序的,除非您使用 setIntervalsetTimeout,或者通过回调或使用 onload 向服务器发出请求。不确定是否还有其他情况。

如果您有类似的内容:

function methodA(fn){
  ...
  fn();
}

那么当您调用 methodA(function(){...}) 时将调用回调

Javascript is sequential except if you use setInterval, setTimeout, or make a request to a server with a callback or using onload. Not sure there are other cases.

If you have something like:

function methodA(fn){
  ...
  fn();
}

Then the callback will be called when you call methodA(function(){...})

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文