Nodejs 浏览器端 JS 代码怎样 block 自身的执行并且能恢复?

Nodejs 浏览器端 JS 代码怎样 block 自身的执行并且能恢复?

想… 我等待 websocket 传回数据期间 JS 对执行过程进行中断, 等到数据传送完成再继续执行余下的代码, 想了半天没找到方案, 用 XMLHttpRequest 的话对于同步的 request 是不能设置 timeout 的, 而 while 死循环无法接受… 不知道还有 JS 代码实现上的方案可以找么

4 回复

要在 Node.js 环境下(具体是在浏览器环境中)实现 JavaScript 代码的阻塞执行并在接收到特定事件后恢复执行,可以使用 Promise 和异步编程技术。这里我们可以通过 fetch API 或者 WebSocket 来实现这种机制。

示例场景:

假设你有一个 WebSocket 连接,并且需要在接收到特定消息之前阻塞当前代码的执行。

实现思路:

  1. 使用 Promise 封装 WebSocket 接收消息的过程。
  2. 在接收到预期的消息后,通过 resolve 解除阻塞。
  3. 使用 .then() 方法来处理后续的操作。

示例代码:

// 创建 WebSocket 连接
const socket = new WebSocket('ws://your-websocket-url.com');

// 定义一个函数来等待特定消息
function waitForMessage(messageType) {
    return new Promise((resolve, reject) => {
        socket.addEventListener('message', function listener(event) {
            const data = JSON.parse(event.data);
            if (data.type === messageType) {
                // 移除监听器以避免多次触发
                socket.removeEventListener('message', listener);
                resolve(data);
            }
        });
    });
}

// 主逻辑
async function main() {
    console.log("开始执行...");
    
    // 阻塞直到接收到特定类型的消息
    const message = await waitForMessage('specific-type');
    console.log("已接收到消息:", message);

    // 继续执行其他操作
    console.log("继续执行...");
}

main();

解释:

  • WebSocket:首先创建一个 WebSocket 连接到指定的 URL。
  • waitForMessage 函数:这是一个返回 Promise 的函数,它会监听 WebSocket 的 message 事件。当接收到特定类型的消息时,Promise 被 resolve,从而解除阻塞状态。
  • 主逻辑main 函数是一个异步函数,使用 await 关键字等待 waitForMessage 函数的完成。这使得在接收到消息之前,所有后续的代码不会执行,实现了代码的阻塞效果。

这种方法利用了现代 JavaScript 的异步特性,避免了传统的死循环或同步请求带来的问题,同时保持了代码的可读性和响应性。


中断执行无外乎暂时禁止用户输入,或者等待服务器返回数据以更新界面。一般来说常见的处理方法不是弹出个waiting提示框之类的,然后在数据返回后取消此提示框吗。 另外就算不能设置timeout,完全可以setTimeout(function(){//中断XMLHttpRequest …

是比较少见的场景… 我尝试用 websocket 来实现浏览器端模块加载 因为需要在 require('filename') 的时候等待请求返回的数据, 必须整个卡住 JS, 为了兼容 Node 上的常用规范语法, 我才去想这种邪门的东西… … 现在想想应该改变的是 Node 才对…

要实现浏览器端的 JavaScript 在等待 WebSocket 数据返回期间阻塞自身执行并能恢复,可以利用 Promiseasync/await 来实现。这样可以在等待过程中不阻塞主线程,并且能够优雅地恢复执行。

以下是一个简单的示例代码:

// 创建一个WebSocket连接
const socket = new WebSocket('ws://your-websocket-url');

// 定义一个异步函数来处理阻塞逻辑
async function waitForData() {
    return new Promise((resolve) => {
        // 监听消息事件
        socket.addEventListener('message', (event) => {
            console.log('WebSocket data received:', event.data);
            resolve(event.data);
        });
    });
}

// 主逻辑函数
async function mainLogic() {
    console.log('开始等待WebSocket数据...');

    // 阻塞当前函数,直到WebSocket数据返回
    const data = await waitForData();
    console.log('WebSocket数据已接收:', data);

    // 继续执行其他逻辑
    console.log('继续执行其他逻辑...');
}

// 调用主逻辑函数
mainLogic();

解释

  1. WebSocket 连接: 创建一个 WebSocket 实例。
  2. 定义异步函数: waitForData 函数返回一个 Promise,当接收到 WebSocket 数据时,通过 resolve 方法将数据传递给外部。
  3. 主逻辑函数: mainLogic 函数中使用 await 关键字等待 waitForData 返回的数据。在此期间,JavaScript 不会阻塞主线程,因此 UI 仍然可以响应用户操作。
  4. 调用主逻辑函数: 最后,调用 mainLogic 函数启动整个流程。

这种方式不仅避免了死循环阻塞主线程的问题,还能保持代码的可读性和维护性。

回到顶部