gpt4 book ai didi

javascript - 我如何保证调用 websocket onopen

转载 作者:行者123 更新时间:2023-11-29 18:56:40 24 4
gpt4 key购买 nike

我在 javascript 中使用 WebSocketWebSocket 需要 url 作为构造函数参数并立即尝试连接。我只能在构造它之后设置onopen方法。

所以,如果 WebSocket 在我设置 onopen 之前已经建立了连接,那么我会错过 onopen 事件!

我怎样才能避免这种情况?

模拟它:

一个)

1) 在 Chrome 中,打开 websocket .2) 按 F12 打开开发者工具。3) 打开控制台4)一次复制并粘贴所有这些代码!输入!

uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);
websocket.onopen = function(evt) { console.log('EHE')};

B)

重复 1-2-3

4) 复制并粘贴这些代码并运行

uri = "ws://echo.websocket.org?encoding=text";
websocket = new WebSocket(uri);

5) 稍等

6) 运行这段代码:

websocket.onopen = function(evt) { console.log('EHE')};

结果:

在 A) 中调用 onopen。在 B) 我们错过了!

最佳答案

由于 Javascript 的单线程事件驱动特性,您描述的情况不会在实际代码中发生。在您当前的 Javascript 部分完成之前,无法触发“打开”事件。因此,您始终能够在事件发生之前设置您的 onopen 事件处理程序。

在调试器或控制台中插入人为暂停是一种人为情况,不会在实际代码中发生。

实际代码中发生的是这样的:

  1. 你调用new WebSocket(uri)
  2. webSocket 内部结构发起 webSocket 连接(异步操作)
  3. webSocket 构造函数在连接完成之前立即返回。
  4. 您的其余代码将运行(包括分配 .onopen 属性和设置您的事件处理程序。
  5. Javascript 解释器运行完您的代码并返回事件循环。
  6. 如果此时 webSocket 已连接,则事件队列中将有一个 open 事件,Javascript 将触发该事件,从而导致您的 .onopen处理程序被调用。
  7. 如果 open 事件尚未完成,Javascript 将等待下一个事件插入事件队列并运行它,一遍又一遍地重复该过程。最终这些事件之一将成为您的 open 事件。

关键是 .onopen 是通过异步事件调用的。因此,它必须通过 Javascript 事件队列。并且,在您当前的 Javascript 部分完成并返回给解释器之前,事件队列中的任何事件都不能运行。这就是 Javascript 的“事件驱动”特性的工作原理。因此,由于该架构,只要将 .onopen 处理程序安装在调用构造函数的同一部分 Javascript 中,就不会错过 onopen 事件。


如果它能让您感到舒服的话,node.js 中有许多 API 都依赖于相同的概念。例如,当您使用 fs.createReadStream(filename) 创建文件流时,您必须创建流,然后添加事件处理程序(其中一个事件处理程序用于 open 事件)。同样的逻辑也适用于那里。由于 Javascript 的事件驱动特性,不存在竞争条件。 open 事件或 error 事件无法在您的其余 Javascript 运行之前触发,因此您始终有机会在事件处理程序被调用之前安装它们。

如果可以同步检测到错误(例如错误的文件名或错误的 uri)并且可以立即触发 error 事件,则使用类似 setImmediate(function() {/* 在此处发送错误事件*/}) 以确保在代码有机会安装事件处理程序之前不会触发错误事件。

关于javascript - 我如何保证调用 websocket onopen,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49210034/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com