问题描述
在阅读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:
-
img.src =path / to / the / image.png;
。 - 浏览器的资源管理代码会查找图像。
- 资源管理在缓存中找到它而不是需要重新验证,因此将图像数据与元素关联并触发
加载
事件。 - 事件系统进入队列回调任何
加载
元素上的事件处理程序的任务,找不到任何任务,也不排队任何任务。 - 我们附上我们的处理程序并附加元素。
- 我们的代码运行完成。
- 我们永远不会得到
加载
或错误
事件回调。
img.src = "path/to/the/image.png";
.- The browser's resource management code goes looking for the image.
- 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. - 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. - We attach our handlers and append the element.
- Our code runs to completion.
- We never get either a
load
orerror
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);
然后同样的情况如下:
- 我们附上我们的处理程序。
-
img.src =path / to / the / image.png;
。 - 浏览器的资源管理代码会查找图像。
- 资源管理在缓存中找到它并且不需要重新验证,因此将图像数据与元素相关联并触发
load
事件。 - 事件系统进入队列任务用于回调元素上存在的任何
加载
事件处理程序。它找到一个,所以当任务队列下一个空时,它会将一个任务排队。 - 我们附加元素。
- 我们的代码运行完成。
- 任务循环从队列中获取下一个任务,恰好是我们的
加载
回调。 - 任务循环调用我们的回调。
- We attach our handlers.
img.src = "path/to/the/image.png";
.- The browser's resource management code goes looking for the image.
- 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. - 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. - We append the element.
- Our code runs to completion.
- The task loop picks up the next task from the queue, which happens to be our
load
callback. - 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.
这篇关于在我们开始收听事件之前发生的事件是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!