Question

First I have developed much in C#, now I'm working on 3D web project and now the most usable language is JavaScript at the moment.

In C# until there becomes the new keywords async/await in new C# specification there was a way to make asynchronous calls by using:

  • delegates
  • Begin/End functions, like: BeginInvoke, EndInvoke
  • IAsync interface

As for JS... Right now I have a need to use some parallel computations and really need a stuff, which is similar to asynchronous work with some locking models like Semaphore, Mutex or other..

As for async/await... I have tried the promises concept, which is implemented in jQuery with its deferred promise:

It remains me async/await concept in C#:

http://msdn.microsoft.com/en-us/library/hh191443.aspx

But I've also have found such concept as WebWorkers:

https://developer.mozilla.org/en-US/docs/Web/Guide/Performance/Using_web_workers

When I first read it, I think it could be also a solution except promises pattern, but if to look from the point of implementing I understand WebWorkers are launching from other threads than a main page execution thread and the functions aren't really asynchronous, they're just callbacks with one option, that they have been added to the Worker() instance, which can be used in main page thread, am I right?

So... I wonder, how can I also implement something similar to the Semaphore in JavaScript?

Thanks!

UPDATE #1 ( more a reply to Doge ):

Let me describe you a simple example, there is an application, which I'm developing. I already using the jQuery deferred object for one thing to await all the texture images I've received, which I was awaiting for.

The link is the next: http://bit.ly/O2dZmQ

It's an webgl application with the three.js library, which is building houses on real data (ps: don't look into code, I know it's not good :) I only recently understand the prototype way of programming in js :) first I was too used to C# and its paradigms ).

So... I have such a task. I must wait when all the textures will be loaded from AJAX and only then I'm setting them as textures for meshes.

Right now... When I've created this question, I thought about redeveloping the source code and thought about WebWorkers use.

What have I think first, which I want to do and what I've done when developed WPF/Silverlight application in C#.

I've done another instance of Worker, which will check asynchronously the task I've described above.

And I have done a very tiny and simple example which I want to use, but have a fail.

As I saw WebWorkers don't accept objects if I want to send it to worker. Alright...

Passing objects to a web worker

There is a JSON.stringify() method... But I've see another thing... JSON.stringify() can't parse an object to string where the are circular references.

Chrome sendrequest error: TypeError: Converting circular structure to JSON

Truly... It's rather disappointing... Because if there is C# or even C++ it's NOT a problem to exchange between instances some objects... Some things could be done with some reinterpret casts or other stuff... And it's not a problem to exchange objects even between different threads even in asynchronous work...

So... For the my aim... What is the best solution? Keep the deffered/promises pattern and not to use WebWorkers?

The tiny source, not full application, but just for a small example, what I want to do:

Textures for a tiny sample:

Minified three.js could be found here:

Était-ce utile?

La solution

It's important to understand that JavaScript has no threads. It has an event loop that executes events, one-by-one, as they come in.

The consequence of this is that if you have a process that takes a while you're blocking all execution. If JavaScript is also needed to do UI stuff like responding to user events or animations, it's a bit of snag. You could try to split up your process into multiple events to keep the event loop running smoothly but that's not always easy to do.

This is where Workers come it. Workers run in their own thread. To avoid issues related to threads the workers don't share memory.

You can communicate with a worker by sending and receiving messages. The messages in turn come in the event loop, so you don't need semaphores or anything that synchronizes threads. If your worker controller is in JavaScript there are never any atomicity issues.

If your workers are simple input->output workers then you can totally slap a Promise layer on top of that. Just keep in mind that Promises themselves don't add threads or asynchronousness.


You can only send Workers messages, that is: strings. You can't send them objects, and certainly not objects that might have references to other objects because again: memory issues.

If I look at your use case I guess the only reason why you might want the Workers is to take advantage of multiple cores that most CPUs have nowadays.

I think what you're doing is loading images as textures into your canvas, and that's what takes up a lot of time? There is no good way to use Workers here since the Worker would need a reference to the canvas, and that's not happening.

Now if instead you needed to do processing on the textures to transform them in some way you could use Workers. Send the image data as a binary string, possibly base64_encoded, do the conversion and send it back. If your image is large the serialization will also take up a fair chunk of CPU time so your mileage may vary.

From what I can tell your resources load pretty quick and there doesn't seem to be a CPU bottleneck. So I don't know if you really need the Workers.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top