本文介绍了在我们开始收听事件之前发生的事件是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读Javascript Promises时,我遇到了一些博客/文章,其中Promise实现首先与Javascript Event模型进行比较,然后是回调模式。

While reading for Javascript Promises, I have come across few blogs/articles where the Promise implementation is first compared with the Javascript Event model and then the callback pattern.

在与事件模型进行比较时,通常会提到 它仍然在WebKit浏览器上运行,虽然我无法在iOS Safari上实现:在文档中添加 img 并期望从这样的代码中获取load事件:

Alternately, this used to be a good example, but Kaiido says it still does on WebKit browsers, although I couldn't make it happen on iOS Safari: Adding an img to a document and expecting to get the load event from code like this:

var img = document.createElement("img");
img.src = "path/to/the/image.png";
img.addEventListener("load", function() {
    // Handle the fact it loaded
}, false);
img.addEventListener("error", function() {
    // Handle the fact it failed
}, false);
someOtherElement.appendChild(img);

从表面上看,由于JavaScript的 run-to,看起来没有竞争条件-completion 语义以及默认情况下我们的JavaScript代码在单个UI线程上运行的事实。但是那里 是一个竞争条件,因为虽然我们的代码将遵循单个线程,但浏览器不是单线程的。所以这可能发生:

On the surface, it looks like there's no race condition there because of JavaScript's run-to-completion semantics and the fact that by default our JavaScript code runs on a single UI thread. But there is a race condition there, because while our code will follow a single thread, the browser is not single-threaded. So this can happen:


  1. img.src =path / to / the / image.png;

  2. 浏览器的资源管理代码会查找图像。

  3. 资源管理在缓存中找到它而不是需要重新验证,因此将图像数据与元素关联并触发加载事件。

  4. 事件系统进入队列回调任何加载元素上的事件处理程序的任务,找不到任何任务,也不排队任何任务。

  5. 我们附上我们的处理程序并附加元素。

  6. 我们的代码运行完成。

  7. 我们永远不会得到加载错误事件回调。

  1. img.src = "path/to/the/image.png";.
  2. The browser's resource management code goes looking for the image.
  3. Resource management finds it in cache and doesn't need to re-verify, so associates the image data with the element and triggers the load event.
  4. The event system goes to queue tasks for callbacks to any load event handlers that are present on the element, doesn't find any, and doesn't queue any tasks.
  5. We attach our handlers and append the element.
  6. Our code runs to completion.
  7. We never get either a load or error event callback.

相反,如果我们首先挂接 然后设置 src

In contrast, if we hook first and then set src:

var img = document.createElement("img");
img.addEventListener("load", function() {
    // Handle the fact it loaded
}, false);
img.addEventListener("error", function() {
    // Handle the fact it failed
}, false);
img.src = "path/to/the/image.png";          // <=== Moved
someOtherElement.appendChild(img);

然后同样的情况如下:


  1. 我们附上我们的处理程序。

  2. img.src =path / to / the / image.png;

  3. 浏览器的资源管理代码会查找图像。

  4. 资源管理在缓存中找到它并且不需要重新验证,因此将图像数据与元素相关联并触发 load 事件。

  5. 事件系统进入队列任务用于回调元素上存在的任何加载事件处理程序。它找到一个,所以当任务队列下一个空时,它会将一个任务排队。

  6. 我们附加元素。

  7. 我们的代码运行完成。

  8. 任务循环从队列中获取下一个任务,恰好是我们的加载回调。

  9. 任务循环调用我们的回调。

  1. We attach our handlers.
  2. img.src = "path/to/the/image.png";.
  3. The browser's resource management code goes looking for the image.
  4. Resource management finds it in cache and doesn't need to re-verify, so associates the image data with the element and triggers the load event.
  5. The event system goes to queue tasks for callbacks to any load event handlers that are present on the element. It finds one, so it queues a task to call it when the task queue is next empty.
  6. We append the element.
  7. Our code runs to completion.
  8. The task loop picks up the next task from the queue, which happens to be our load callback.
  9. The task loop calls our callback.

现在,碰巧这种行为非常令人厌烦现代浏览器不再这样做(尽管它仍然在WebKit上,我无法确认)。虽然我仍然像它那样编码(第二个例子),因为可以,这是浏览器工作的有效方式。

Now, it happens that this behavior was sufficiently irksome that modern browsers don't do it anymore (although Kaiido says it still does on WebKit, I can't confirm that). Although I still code as though it does (the second example), because it could, it's a valid way for the browser to work.

这篇关于在我们开始收听事件之前发生的事件是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-03 21:48