我理解为什么浏览器供应商不想帮助我阻止他们的 UI 线程。但是,我不明白为什么会有:
- Web Worker 中的 no sleep(2)
- 没有同步的 WebSockets API
有一个同步的 FileSystem API。还有一个同步 IndexedDB API。在我看来,这似乎是一个矛盾。
我理解为什么浏览器供应商不想帮助我阻止他们的 UI 线程。但是,我不明白为什么会有:
有一个同步的 FileSystem API。还有一个同步 IndexedDB API。在我看来,这似乎是一个矛盾。
WebWorkers没有可用功能的原因sleep()
很简单:您不需要它。 sleep
是一个同步函数,(它在返回之前一直阻塞)在 WebWorkers 的异步上下文中没有意义。
如果您向 WebWorker 发送消息,它不会阻塞等待响应;响应作为消息发送到您的消息处理函数。如果您想在发送响应之前等待一段时间,您不会使用sleep
,您会在调用函数时使用setTimeout
并触发消息。
同样,如果您使用 WebWorkers 进行 WebSocket 数据传输,您将从主线程接收消息,通过 websocket 异步发送数据包,然后在响应处理程序中将消息发送回主线程。sleep
使用同步函数没有合乎逻辑的地方。
至于为什么 WebSockets 没有像文件系统那样的同步模式,主要区别在于文件系统不是通过网络访问的。一般来说,对于基于网络的函数来说,异步 API 更可取,所以我想我不认为它有太大的矛盾。
IDB只支持 3 个浏览器,它们都没有实现同步 API,所以我不认为这是同步 API 的一个光辉例子。事实上,我认为这就是人们会定义 API 而不会费心去实现它的矛盾。
一点都不明显:TCP协议也是一种网络协议,对吧?它经常在同步模式下使用,因为它使应用程序更易于开发和调试。
在我看来,异步模式在单线程应用程序的上下文中很明显,当您不希望 I/O 阻塞 UI 时。例如,如果您打算使用 Web Worker 来处理后台 I/O,那就不太明显了。将同步 Websocket 与 Web Worker 结合起来确实很方便。
最后,假设文件读取调用将很快完成是不明智的。如果 IO 没有响应,您应该总是有一个超时或接受您的应用程序将挂起的事实。
对我来说,这是很明显的。
FileSystem API 和 IndexedDB API 以毫秒为单位工作,因此您现在可以放心拥有您的数据,相反,WebSockets API 必须至少慢 100 倍,数据必须在狂野的互联网上传输,因此很明显使其异步。你的回应甚至永远不会回来。
索引数据库不会长时间阻塞执行,很可能它会在几毫秒内给出结果,我们不希望在索引数据库中存储数百万条记录。与文件 API 相同,大多数 API 将导致更快的执行。
同步 API 也会导致竞争条件,并且需要多线程同步等,这会增加编程复杂性。相反,基于消息的线程更容易编程,并且我们没有同步问题。
此外,大多数 javascript 引擎都是稳定的,人们熟悉异步编程方式。编写工人更容易也是唯一的方法。改变这一点需要大量重写 javascript 引擎。引入更多的原生 API 将使工作者编程更加复杂。不同的操作系统和不同的架构或设备 wiki 引入了更多的复杂性。
由于V8 已经实现了 ES2017 await/async,我可以将它与支持 Promise 的库一起使用,并且我不再需要如此糟糕的同步 API。