首先,我在C#中开发了很多,现在我正在开发3D网络项目,现在最有用的语言是JavaScript。
在C#中,在新C#规范中出现新关键字async/await
之前,有一种方法可以通过以下方式进行异步调用:
至于JS ......现在我需要使用一些并行计算并且真的需要一些东西,这类似于使用Semaphore,Mutex或其他一些锁定模型的异步工作。
至于async / await ...我已经尝试了promises概念,它在jQuery中实现了延迟的承诺:
它仍然是我在C#中的异步/等待概念:
http://msdn.microsoft.com/en-us/library/hh191443.aspx
但我也发现了WebWorkers
:
https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers
当我第一次阅读它时,我认为除了promises模式之外它也可能是一个解决方案,但是如果从实现的角度来看,我理解WebWorkers是从主页面执行线程以外的其他线程启动而且函数不是真的是异步的,它们只是带有一个选项的回调,它们已被添加到Worker()
实例中,可以在主页面线程中使用,我是对的吗?
所以...我想知道,我怎样才能在JavaScript中实现与Semaphore
类似的东西?
谢谢!
更新#1 (更多回复Doge
):
让我来形容一个简单的例子,有一个应用程序,我正在开发。
我已经将jQuery延迟对象用于to await all the texture images I've received, which I was awaiting for
。
链接是下一个:http://bit.ly/O2dZmQ
这是一个带有webgl
库的three.js
应用程序,它正在构建真实数据库(ps:不看代码,我知道它不好:)我最近才了解原型在js中编程的方式:)首先我太熟悉C#及其范例了。
所以......我有这样的任务。我必须等待所有纹理从AJAX加载,然后才将它们设置为网格纹理。
现在......当我创建这个问题时,我考虑重新开发源代码并考虑WebWorkers使用。
我首先想到的是,在C#中开发WPF / Silverlight应用程序时我想做什么以及我做了什么。
我已经完成了 Worker 的另一个实例,它将异步检查我上面描述的任务。
我做了一个非常小而简单的例子,我想用它,但是失败了。
我看到 WebWorkers 如果我想将其发送给工作人员,则不接受对象。好吧......
Passing objects to a web worker
有一个JSON.stringify()
方法......但我看到了另一件事... JSON.stringify()无法将对象解析为字符串circular references
。
Chrome sendrequest error: TypeError: Converting circular structure to JSON
真的......这是相当令人失望的...因为如果有C#甚至是C ++那么 NOT 在实例之间交换某些对象的问题......有些事情可以通过一些重新解释转换来完成或其他东西......即使在异步工作中,即使在不同的线程之间交换对象也不是问题......
所以...为了我的目标......什么是最好的解决方案?保留deffered / promises模式而不是使用 WebWorkers ?
微小的资源,不是完整的应用程序,而只是一个小例子,我想做的事情:
微小样本的纹理:
在这里可以找到缩小的三个.js:
答案 0 :(得分:3)
了解JavaScript 没有线程非常重要。它有一个事件循环,在它们进入时逐个执行事件。
这样做的结果是,如果你有一个过程需要一段时间才能阻止所有执行。如果还需要JavaScript来做UI响应用户事件或动画等内容,那就有点麻烦了。您可以尝试将您的流程拆分为多个事件,以保持事件循环顺利运行,但这并不容易。
这是Workers
来的地方。工人用自己的线程运行。为了避免与线程相关的问题,工作者不共享内存。
您可以通过发送和接收消息与工作人员进行通信。消息反过来来自事件循环,因此您不需要信号量或任何同步线程的东西。如果您的工作者控制器是JavaScript,那么从来没有任何原子性问题。
如果你的工人是简单的input->output
工人,那么你可以完全拍打Promise图层。请记住,Promises本身不会添加线程或异步。
您只能发送Workers消息,即:字符串。你不能发送它们对象,当然也不能发送可能引用其他对象的对象,因为:内存问题。
如果我查看您的用例,我想您可能希望工作者的唯一原因是利用大多数CPU现在拥有的多个核心。
我认为你正在做的是将图像作为纹理加载到画布中,这是需要花费大量时间的?没有好办法在这里使用工人,因为工人需要参考画布,而这种情况并没有发生。
现在,如果您需要对纹理进行处理以某种方式对其进行转换,那么可以使用Workers。将图像数据作为二进制字符串发送,可能是base64_encoded,进行转换并将其发回。如果您的图像很大,序列化也会占用相当多的CPU时间,因此您的里程可能会有所不同。
从我可以告诉您的资源加载非常快,似乎没有CPU瓶颈。所以我不知道你是否真的需要工人。