You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js readline模块异常:获取用户输入后程序停滞

Node.js readline输入后程序停滞问题排查与修复

问题概述

使用JavaScript解决DSA问题时,通过Node.js的readline/promises模块获取用户输入,程序在完成输入后陷入停滞,无任何报错信息。

提供的代码

业务代码

/* Given an array and Q queries, where a query looks like the following,
(l,r)--> l,r are the indices of the array. For each query, you need to find the sum between the given indices
*/
import { getUserInput } from "../index.js";

async function preCompute() {
  let arraySize = 0;
  // get the number for user inputs
  arraySize = await getUserInput("Enter the array size : ");
  console.log("ARRAY SIZE", arraySize);
  const userInputs = [];
  for (let i = 0; i < Number(arraySize.trim()); i++) {
    const currentUserInput = await getUserInput("Enter the number");
    userInputs.push(Number(currentUserInput.trim()));
  }
  const prefixSumArray = [];
  for (let i = 0; i < arraySize; i++) {
    if (i === 0) {
      prefixSumArray[i] = userInputs[i];
    } else {
      prefixSumArray[i] = prefixSumArray[i - 1] + userInputs[i];
    }
  }
  let Q = 0;
  Q = await getUserInput("Enter the number of queries i.e Q");
  for (let i = 0; i < Q; i++) {
    const queryInput = await getUserInput(
      "Enter space separated value for l and r"
    );
    const [l, r] = queryInput.split(" ");
    console.log(
      `Sum between l and r: ${\n        l !== 0 ? prefixSumArray[r] - prefixSumArray[l - 1] : prefixSumArray[r]\n      }`
    );
  }
}

preCompute();

index.js代码

import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

const rl = readline.createInterface({
  input,
  output,
});

export const getUserInput = (prompt) => {
  return new Promise((resolve) => {
    rl.question(prompt, (answer) => {
      console.log("Running callback to resolve");
      resolve(answer);
    });
  });
};

问题原因分析

  1. readline接口未关闭:创建的rl实例在所有输入操作完成后没有调用rl.close(),Node.js会保持标准输入(stdin)的监听状态,导致事件循环无法退出,程序看起来陷入停滞。
  2. 输入未显式转换为数字:arraySize、Q等变量直接使用字符串类型参与循环条件判断,虽然JavaScript会隐式转换,但容易引发意外问题(比如输入包含非数字字符时循环逻辑出错)。
  3. 模板字符串语法错误:console.log中的模板字符串存在语法错误,表达式部分的换行写法不符合规范,可能导致程序静默失败或输出异常。

解决方案

1. 完成输入后关闭readline接口

在所有输入和查询处理完成后,调用rl.close()终止readline接口的监听,让Node.js事件循环正常退出。

2. 显式转换输入为数字

将获取的用户输入统一转换为数字类型,避免隐式转换带来的潜在问题。

3. 修复模板字符串语法错误

调整模板字符串中表达式的写法,确保语法合规。

修改后的代码示例

修改后的index.js

import readline from "node:readline/promises";
import { stdin as input, stdout as output } from "node:process";

export const rl = readline.createInterface({
  input,
  output,
});

export const getUserInput = (prompt) => {
  return new Promise((resolve) => {
    rl.question(prompt, (answer) => {
      console.log("Running callback to resolve");
      resolve(answer.trim());
    });
  });
};

修改后的业务代码

import { getUserInput, rl } from "../index.js";

async function preCompute() {
  try {
    // 获取数组大小并转为数字
    const arraySizeStr = await getUserInput("Enter the array size : ");
    const arraySize = Number(arraySizeStr);
    console.log("ARRAY SIZE", arraySize);

    // 获取数组元素
    const userInputs = [];
    for (let i = 0; i < arraySize; i++) {
      const numStr = await getUserInput(`Enter number ${i + 1}: `);
      userInputs.push(Number(numStr));
    }

    // 计算前缀和
    const prefixSumArray = [];
    for (let i = 0; i < arraySize; i++) {
      prefixSumArray[i] = i === 0 ? userInputs[i] : prefixSumArray[i - 1] + userInputs[i];
    }

    // 获取查询次数并转为数字
    const QStr = await getUserInput("Enter the number of queries i.e Q: ");
    const Q = Number(QStr);

    // 处理查询
    for (let i = 0; i < Q; i++) {
      const queryInput = await getUserInput("Enter space separated value for l and r: ");
      const [lStr, rStr] = queryInput.split(" ");
      const l = Number(lStr);
      const r = Number(rStr);
      
      // 校验索引合法性
      if (l < 0 || r >= arraySize || l > r) {
        console.log("Invalid indices: l and r must be within array bounds and l <= r");
        continue;
      }
      
      const sum = l !== 0 ? prefixSumArray[r] - prefixSumArray[l - 1] : prefixSumArray[r];
      console.log(`Sum between l=${l} and r=${r}: ${sum}`);
    }
  } catch (err) {
    console.error("Error occurred:", err);
  } finally {
    // 关闭readline接口,让程序正常退出
    rl.close();
  }
}

preCompute();

额外说明

  • 添加try/catch块处理可能的异常(比如输入非数字时的转换错误),提升程序健壮性。
  • 对查询的索引进行合法性校验,避免数组越界错误。
  • 在getUserInput中自动trim输入,减少后续重复处理。

内容的提问来源于stack exchange,提问作者Abhishek Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:45:17