22

I understand why browser vendors don't want to help me block their UI thread. However, I don't understand why there is:

  1. no sleep(2) in Web Workers
  2. no synchronous WebSockets API

There is a synchronous FileSystem API. There is also a synchronous IndexedDB API. To me, it seems like a contradiction.

Janus Troelsen
  • 17,537
  • 13
  • 121
  • 177
  • 3
    1. why would you need sleep in a webworker? webworker are activated when you postMessage to them – Fireblaze Oct 04 '12 at 15:51
  • 1
    @Fireblaze: Because ```part_one(); usleep(100*1000); part_two();``` looks better than ```part_one(function(){setTimeout(100,function(){part_two();})})``` – Janus Troelsen Oct 08 '12 at 11:06
  • 1
    javascript is the only language that is designed to be non blocking. every person who uses alert, confirm, prompt, syncronous filesystem, syncronous ajax and sleep (IE has it), srsly should consider learning javascript design patterns. you are able to build heavy and awesome applications using just one event oriented thread even though it feels like it runs on multiple threads. – GottZ Mar 01 '13 at 09:19
  • @Jan-StefanJanetzky: Do you have a source on your claim that JavaScript was "designed to be non-blocking"? How come blocking function calls like `alert`, `confirm`, `prompt` have been there since before the modern way of JavaScript became prevalent? Also, why would I make programming for myself harder ("feels like it runs on multiple threads") when I don't even get the performance benefit of actual multiple threads? I don't think JavaScript is a good language for concurrency, and I think it's because it started out imperative but now wants to be something else. – Janus Troelsen Mar 01 '13 at 14:45
  • 1
    @JanusTroelsen: alert, confirm and prompt are not related to the language in any kind of way. they are simply methods kept syncronous because taking them to asyncronous behavior would break most applications that require them being blocking. it seems like you are one of theese people who think javascript exists only within browsers. if you compile v8 or spidermonkey from source into an application you will not have alert, confirm or prompt at all. not even setTimeout. the language will just be fully event oriented. – GottZ Mar 01 '13 at 15:29
  • @JanusTroelsen: search for: event driven programming – GottZ Mar 01 '13 at 15:39
  • @Jan-StefanJanetzky: I assert that the event-driven JavaScript programming style became popular after the language was "designed" (I quoted that because I think it was barely designed, I think it was a quick hack by Eich). And I think that the presence of `alert` et. al shows that nobody realized back then that the future of JavaScript was going to be event-driven programming. I think you are confusing programming paradigms of coding style and programming paradigms of languages. Every language with anonymous functions lends itself to event-driven programming. – Janus Troelsen Mar 01 '13 at 22:03
  • @JanusTroelsen If I recall correctly, Javascript was intended to be an in-browser Scheme implementation, which was retro-actively Java-ified for a marketing gimmick. It is, at its core, not a procedural, but a functional language. Much of the "craze", as you described it, is simply Continuation Passing Style. It's a well established pattern in languages that don't support tail-call optimization. – saml Mar 06 '13 at 18:48

5 Answers5

15

The reason why there's not a sleep() function available to WebWorkers is simple: you don't need it. sleep is a synchronous function, (it blocks until it returns) which doesn't make sense in the asynchronous context of WebWorkers.

If you send a message to a WebWorker, it doesn't block waiting for a response; the response is sent as a message to your message handler function. If you want to wait a certain amount of time before sending a response, you wouldn't use sleep, you'd use setTimeout and fire a message off when your function gets called.

Similarly, if you're using WebWorkers for WebSocket data transmission, you'd receive a message from the main thread, send a packet via websocket asynchronously, then in the response handler you'd send a message back to the main thread. There's no logical place to use a synchronous sleep function.

As far as why there's not a synchronous mode for WebSockets like there is for the filesystem, the primary difference is that the filesystem isn't accessed across the network. Generally, asynchronous APIs are preferable for network-based functions, so I guess I don't see it as much of a contradiction.

IDB is only supported by 3 browsers, none of which have implemented the synchronous API, so I don't see that as a shining example of synchronous APIs. Inf fact, I think that's the contradiction that people would define an API and not bother to implement it.

saml
  • 6,262
  • 1
  • 30
  • 29
  • How is it a contradiction that a unimplemented standardized API exists? The people making the standards (W3C) are seperate from the browser vendors! I am glad the API is at least defined. – Janus Troelsen Nov 26 '12 at 20:59
  • 1
    I don't understand your point about blocking not making sense in WebWorkers. Everything you normally do is blocking! That's why threads exist. JavaScript is a procedural imperative language, it is primarily designed for writing blocking code. WebWorkers give us threads, now the callback mess could have been avoided (since JavaScript doesn't encourage this coding style). But no. – Janus Troelsen Nov 26 '12 at 21:03
  • 1
    Regarding "Generally, asynchronous APIs are preferable for network-based functions": I'd really like a source for this! Let's take the POSIX sockets. How are they commonly used? Blocking! What do you mean by preferable? I see blocking network code in its own thread as preferable since that's what people have been doing for 30 years before the async craze started. – Janus Troelsen Nov 26 '12 at 21:07
  • Javascript isn't a procedural imperative language: https://twitter.com/BrendanEich/status/309767675293347841 – saml Mar 07 '13 at 21:24
9

It is not obvious at all : TCP protocol is a network protocol too, right ? And it is quite often used in synchronous mode, because it makes applications simpler to develop and debug.

In my opinion Async mode is obvious in the context of mono threaded applications, when you don't want I/Os to block a UI. It is very less obivous if you intend to use web workers, for instance, to handle background I/Os. It would indeed be convenient to have synchronous Websocket in conjonction with web workers.

Finally, it is just not carful to assume that a file read call will be done and quickly. You should always have a timeout or accept the fact that your app is going to hang if IO doesn't respond.

Mayur Birari
  • 5,844
  • 8
  • 32
  • 61
nico
  • 199
  • 1
  • 1
7

For me it is quite obvious.

FileSystem API & IndexedDB API works in order of milliseconds so you can trust have your data right now, instead it, WebSockets API must be at least 100 times slower, the data must fly over the wild internet, so it's obvious to make it asynchronous. Your response can even never back.

enter image description here

Ma Jerez
  • 3,428
  • 2
  • 16
  • 20
  • I don't know how you can assume latencies like these. For example, [Firefox allows up to 50 MB of IndexedDB data per site](http://support.mozilla.org/en-US/questions/818987). Why does Node.js features asynchronous file system access? – Janus Troelsen Oct 09 '12 at 21:09
  • well these are times for typical calls to these with low data's sizes, like images or cookies, if data's size is increased obviously it increases the transmission time. Node.js allows asynchronous file system access because it have nothing to do with these web Apis, it is intended to be server side not client side. – Ma Jerez Oct 10 '12 at 11:15
  • 1
    How does it make a difference if it runs on the server or on the client? It is still a file system API, and it is going to be used in pretty much the same way. – Janus Troelsen Nov 26 '12 at 20:56
3

Indexed db will not block execution for longer time, most likely it will give result in few milli seconds and we are not expecting to store millions of records in indexed db. Same with file API, most API will result in quicker execution.

Also synchronous API will lead to race conditions and will require multi thread synchronization etc which will increase programming complexity. Instead message based threading is easier to program and we are free from synchronization issues.

Also most javascript engines are stable, and people are familiar with async programming ways. It's easier and only way to write worker. Changing this will require huge rewrite of javascript engines. Introducing more native API will make worker programming more complicated. Different os and different architecture or devices wiki introducr more complexity.

Akash Kava
  • 37,127
  • 20
  • 114
  • 162
  • I don't think this really answers the question as much as it explains synchronous vs asynchronous data models. – saml Oct 05 '12 at 17:54
  • regarding race conditions: I do not think it is possible to open the same DB from two different workers, or pass an open handle into a worker. Just as I would not expect to be able to pass a WebSocket to a worker. So if it cannot be accessed concurrently, how can I get any deadlocks? – Janus Troelsen Oct 08 '12 at 10:36
1

Since V8 has implemented ES2017 await/async, I can use that with Promise-enabled libraries, and I don't need the synchronous API so badly anymore.

Janus Troelsen
  • 17,537
  • 13
  • 121
  • 177