【问题标题】:Why in javascript deferred callbacks don't create race conditions? [duplicate]为什么在 javascript 中延迟回调不创建竞争条件? [复制]
【发布时间】:2015-09-29 18:44:33
【问题描述】:

所以我想写一些类似于从 IndexedDB 文档中截取的内容:

var req;
var store = getStore();
req = store.count();
req.onsuccess = function(evt) {
  console.log("success: " + evt.result);
};
req.onerror = function(evt) {
  console.error("add error", this.error);
};

https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB

并开始想知道为什么 javascript 允许在调用后定义(延迟?)回调以及为什么它不会导致竞争条件? 有人可以分享一下吗?

那么,javascript 如何确保在分配回调之前不执行异步调用?

谢谢!

【问题讨论】:

  • JS 是单线程的,因此 store.count() 调用的异步部分将在您当前的代码之后执行,因此所有回调都已设置。
  • “您当前的代码”是什么意思? js中解析时间和执行时间不一样吗?
  • 我在您的代码中没有看到任何承诺或延期???如果有的话,解释会有所不同。
  • 无论是否有延迟,“异步”调用可能会立即执行而不会造成任何伤害。它是调用异步触发的回调的事件。

标签: javascript promise race-condition deferred deferred-execution


【解决方案1】:

JS是单线程的,所以你当前代码的实际执行顺序如下:

store.count();              // trigger some async code
req.onsuccess; req.onerror; // attach the callbacks
                            // some other code in the same function/scope may follow

                            // your code is finished; next item from event queue is executed

store.count();              // the async part gets executed
req.onsuccess();            // after the async part (or within it) 
                            // one of your callbacks gets executed.

所以你可以看到,当你附加你的回调时,只要你在当前函数完成并且JS事件队列寻找下一个要执行的代码块之前这样做,这并不重要。


关于您的评论:不,现代 JS 引擎中的解析和执行时间并不相同。引擎会编译您的代码,然后执行它。 (有一些例外情况,使用回退到旧的解释器样式,但在大多数情况下应该不相关)。

【讨论】:

  • 我真正想问的是javascript如何确保在分配回调之前不会执行异步调用?
  • 我认为异步调用会在调用时而不是在解析时进行调度?
  • @pawciobiel。不,sirko 详细说明的顺序是正确的。把它想象成直接执行你的代码到最后,但是像 getStore() 这样的异步东西实际上不会在你当前的功能块结束之前运行,所以你可以安全地在初始分配之后添加事件处理程序。正如您所说,它们在被调用时被安排,但直到下一个滴答声才会真正运行
猜你喜欢
  • 2019-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
  • 2019-03-02
  • 2010-12-07
相关资源
最近更新 更多