从 Flash 调用的 JavaScript 代码在哪个线程上执行?

Posted

技术标签:

【中文标题】从 Flash 调用的 JavaScript 代码在哪个线程上执行?【英文标题】:What thread does JavaScript code called from Flash execute on? 【发布时间】:2010-10-05 20:09:20 【问题描述】:

据我了解,所有 javascript 代码都是事件驱动的,并且在单个浏览器线程上执行。

但是,我有一些 JavaScript 函数是从位于同一页面上的 SWF 对象中调用的。该代码是否以与常规 JS 代码相同的方式运行,还是在某个单独的 Flash 线程上运行?

如果它在单独的线程上,我可以使用 setTimeout() 让它在 JS 事件线程上运行吗?例如:

function calledFromFlash() 
    setTimeout(doActualWork, 0);


function doActualWork() 
    // blah blah blah

【问题讨论】:

【参考方案1】:

它仍然在同一个线程上。但是,出于大多数实际目的,如果您有一个运行时间很长的 JavaScript,以至于您担心您的“主要”任务可能会阻止来自 setTimeout 的调用,那么您应该考虑重新审视您的底层方法。

赏金更新:

为了扩展 JavaScript 中更一般的线程问题,a great discussion Bobince 给出了一个非常有启发性的答案。他引用了一些非常有趣的场景,可能会质疑我们是否真的可以将 JS 视为单线程,他的结论是“不完全”。

我同意 cmets 的结论是,从 JS 运行时内部的角度来看,宇宙是单线程的,但是 因为围绕 JS 沙箱的基础设施是不是 单线程,它可以到达沙箱内部并以意想不到的方式弄脏状态。从运行时内部,一些未知实体可以“暂停自然法则”并改变周围的事物。但是运行时没有线程结构来本地处理这种情况。

我认为解决这个问题最重要的方法是问在实际场景中多线程是什么意思?通常线程问题归结为诸如同步之类的问题,我们必须假设浏览器供应商已经为我们解决了这些问题,因为 JavaScript 没有原生结构,甚至无法自己尝试处理它。如果没有工具来修复它,那么绞尽脑汁是没有好处的;没有互斥体或锁。

因此,撇开这些灾难性问题不谈,我们可能会遇到一些事情,比如某个值可能会意外地从我们下面被更改。但是编写良好的代码应该可以接受。即使在 Bobince 的示例中,所涉及的所有代码仍然是我们自愿包含在页面中的代码(甚至是我们自己编写的),因此可以肯定的是,如果在您的主调用堆栈表面上“阻塞”时触发该代码可能会令人惊讶。但是再次谈到实际问题,在那种情况下你能对自己做的最糟糕的事情是什么?没什么太严重的。

这是我的长期说法:我不知道浏览器供应商提供的任何文档,他们明确说明他们的 JS 实现是否是单线程的,但我怀疑这是否重要。

【讨论】:

嗨,雷克斯,非常感谢您的回答。跟进:这是真正的跨浏览器吗,你知道支持它的任何参考资料吗?我不担心呼叫被阻止,我只是想确保回调代码和我的常规事件之间没有同步问题。 JavaScript 根本没有处理多线程的机制。这本身就是证明它不是多线程的。这篇文章本身不是证据,但提出了一个很好的观点,即 JS 中的线程问题毫无意义:damienkatz.net/2006/04/how_to_create_a.html 如果你在谷歌上搜索关于 JS 线程的信息,你会发现很多博客都说 JS 是线程的,但这都是基于对 JS 引擎的工作原理的误解。主机(浏览器)。 @Rex:嗨,Rex,我开始悬赏这个问题,希望能得到更多证据;我知道浏览器中的 JS 是单线程的,这本身就是非常好的证据,但它并不是真正确凿的证明。如果你能挖掘出更实质性的东西(也许在 Firefox 插件 API 源代码中?),或者可能编写一个小脚本以某种方式显示 JS 端永远不会并发,我将不胜感激。不要误会,你的回答已经足够了;我只是出于好奇是否可以挖掘出任何无可辩驳​​的证据来开始赏金,理想情况下适用于每个浏览器。 @Cameron 在另一个问题上对这个话题进行了很好的讨论。 Bobince 的回答是彻底的,但大多数评论者(以及我自己)不同意他的结论,即 JS 不是完全单线程的。从 JS 沙箱内部的角度来看,宇宙是单线程的。但就 Bobince 而言,围绕沙箱的基础设施是多线程的,有时会以意想不到的方式到达内部并与调用堆栈混为一谈。 (讨论:***.com/questions/2734025/…)【参考方案2】:

Flash ExternalInterface 调用使用与主应用程序相同的处理线程同步完成。从 Flash 到 JS 的调用被视为与 JS 应用程序中的任何事件绑定相同。

我已经 blogged about 在必要时使用它来为您服务,尽管这通常很麻烦。

这里有一些其他资源提到这个事实:linklinklinklink

我希望这有助于澄清事情。

【讨论】:

某些链接已损坏,我遇到了可能相关的问题,您能修复链接吗? 我不确定其他任何可能已过期的链接,但我的博客链接更改为:labs.tomasino.org/as3-synchronous-url-xml-loading.html

以上是关于从 Flash 调用的 JavaScript 代码在哪个线程上执行?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript -> Flash 抛出“错误调用 NPObject 方法”

Flash AS3:调用javascript函数

ActionScript 3 从Flash文件(AS3)调用Javascript(JS)函数

将数组从 Flash (AS3) 发送到 JavaScript

在HTML中,如何写js代码(或者别的)以实现flash的点击事件

通过单击网页中的播放按钮在Flash播放器中播放音乐