JavaScript等待用户输入的阻塞执行方案分享

最近在负责百度TDA平台的aiCalling二期,在给AI智能助手添加澄清功能的时候出现了一个需求:需要等待用户在输入框中输入内容并确认后,才能继续执行后续代码。简单来说,就是需要在同步代码流程中实现"阻塞等待"的效果。

澄清功能图如下:

需求伪代码如下:

javascript 复制代码
while(条件1) {
  while(条件2) {
    // 一些代码
    等待用户输入  // 需要在这里阻塞,直到用户输入后才继续
    // 后续代码
  }
}

当想到阻塞同步代码这个词条的时候我第一个想的就是async await

async实际上就是Promsie的语法糖,当 JavaScript 引擎遇到 async 函数时,会将其转换为一个返回 Promise 的函数。而在函数内部,每个 await 表达式都会暂停函数的执行,直到 Promise 解决,然后以 Promise 的解决值恢复执行(await只暂停async函数内部的执行,不会阻塞主线程,JavaScript 的事件循环会继续处理其他任务)。

我这里直接使用new Promise通过await来阻塞执行,等待resolve()后结束阻塞:

javascript 复制代码
async function() {
  // 前置代码...
  
  await new Promise(resolve => {
    const checkTextEmpty = () => {
      if (this.questionText !== '') { // 用户已输入并确认
        // 一些逻辑代码...
        
        resolve(); // 解除阻塞
      } else {
        setTimeout(checkTextEmpty, 200); // 200ms后再次检查
      }
    };
    checkTextEmpty();
  });
  
  // 后续代码...
}

此时使用方案为:setTimeout轮询+Promise阻塞。


本文就此结束了吗?当然没有,肯定有同学会提出疑问:轮询一般是下下策,比如使用setTimeout会来带性能损耗等诸多问题,有没有更好的解决方案?

有的兄弟有的。

在和mentor进行code review后,mentor提出一个优化方案:通过现有事件总线的发布订阅来代替setTimeout轮询。

于是优化版的代码如下:

javascript 复制代码
// 处理用户输入的函数
setQuestionText = value => {
  this.questionText = value;
  if (value !== '') {
    window.globalEvent.emitEvent('questionTextChanged', value);
  }
};

// 主逻辑
async function() {
  // 前置代码...
 
  await new Promise(resolve => {
    const eventHandler = event => {
      //  一些逻辑代码...
      
      event.remove(); // 移除事件监听,避免内存泄漏
      resolve(); // 解除阻塞
    };
    //订阅用户输入事件
    window.globalEvent.listenEvent('questionTextChanged', eventHandler);
  });
  
  // 后续代码...
}

此时的方案为:发布订阅+Promise阻塞,这个方案是目前最终解决方案,避免了轮询方案递归setTimeout的复杂性和潜在内存泄漏风险。

本文重在方案分享与探讨,欢迎来分享更优或平替解决方案。

相关推荐
jqq6663 分钟前
解析ElementPlus打包源码(五、copyFiles)
前端·javascript·vue.js
Awu12277 分钟前
⚡IndexedDB:现代Web应用的高性能本地数据库解决方案
前端·indexeddb
似水流年_zyh8 分钟前
canvas写一个选择音频区域的组件
前端·canvas
wordbaby33 分钟前
TanStack Router 实战:如何优雅地实现后台管理系统的“多页签” (TabList) 功能
前端·react.js
凌览1 小时前
2026年1月编程语言排行榜|C#拿下年度语言,Python稳居第一
前端·后端·程序员
user86158185781541 小时前
Element UI 表格 show-overflow-tooltip 长文本导致闪烁的根本原因与解法
前端
不会写前端的小丁1 小时前
前端首屏渲染性能优化小技巧
前端
还不秃顶的计科生1 小时前
defaultdict讲解
开发语言·javascript·ecmascript
晴虹1 小时前
lecen:一个更好的开源可视化系统搭建项目--组件和功能按钮的权限控制--全低代码|所见即所得|利用可视化设计器构建你的应用系统-做一
前端·后端·低代码
爱分享的鱼鱼1 小时前
Pinia 深度解析:现代Vue应用状态管理最佳实践
前端·后端