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

Node.js异步请求下while循环无限循环及Express中间件适配问题

解决Node.js异步请求导致while循环无限的问题

问题根源

你的代码中同步while循环和异步request回调的执行逻辑不兼容:while是同步执行的,会瞬间发起大量请求,完全不会等待回调函数填充数组,导致数组长度始终满足循环条件,陷入无限循环。

解决方案

1. 改用Promise风格的请求库(推荐)

request库已被废弃,建议使用原生支持Promise的axios或node-fetch,结合async/await实现异步循环,同时Express完全支持异步中间件(只需正确处理错误)。

示例代码(使用axios)

const axios = require('axios');

// 定义异步Express中间件
async function fetchFilteredData(req, res, next) {
  let filteredResults = [];
  let currentApiUrl = searchLink.apiLink;

  try {
    while (filteredResults.length <= 10) {
      // 等待请求完成
      const response = await axios.get(currentApiUrl);
      const apiData = response.data;

      // 过滤符合条件的数据
      const validItems = apiData.results.filter(item => 
        item.title !== null &&
        item.description !== null &&
        item.content !== null &&
        item.language === "english"
      );

      filteredResults.push(...validItems);

      // 检查是否有下一页,没有则终止循环
      if (!apiData.nextPage) break;
      // 更新下一页URL
      currentApiUrl = `${searchLink.apiLink}&page=${apiData.nextPage}`;
    }

    // 将结果返回给客户端
    res.json(filteredResults);
  } catch (error) {
    // 捕获错误并传递给Express错误处理中间件
    next(new Error(`API请求错误: ${error.message}`));
  }
}

// 在路由中使用该中间件
app.get('/filtered-data', fetchFilteredData);

2. 兼容旧版request库(使用promisify)

如果必须使用request,可以用Node.js内置的util.promisify将其转换为Promise风格:

const request = require('request');
const { promisify } = require('util');
const requestAsync = promisify(request);

async function fetchFilteredData(req, res, next) {
  let filteredResults = [];
  let currentApiUrl = searchLink.apiLink;

  try {
    while (filteredResults.length <= 10) {
      // 等待请求完成,开启json参数自动解析响应
      const { body: apiData } = await requestAsync({ url: currentApiUrl, json: true });

      const validItems = apiData.results.filter(item => 
        item.title !== null &&
        item.description !== null &&
        item.content !== null &&
        item.language === "english"
      );

      filteredResults.push(...validItems);

      if (!apiData.nextPage) break;
      currentApiUrl = `${searchLink.apiLink}&page=${apiData.nextPage}`;
    }

    res.json(filteredResults);
  } catch (error) {
    next(new Error(`API请求错误: ${error.message}`));
  }
}

关键说明

  • Express异步中间件:Express支持异步函数作为中间件,只需在函数内部用try/catch捕获错误,并调用next(err)传递给错误处理中间件即可,无需纠结“标准函数”限制。
  • 顶层await问题:CommonJS模块(.js)不支持顶层await,必须将逻辑包裹在异步函数中执行;若要使用顶层await,需将文件改为ES模块(.mjs或在package.json中设置"type": "module")。
  • 循环终止条件:务必添加nextPage存在性检查,避免在API无下一页时继续发起无效请求。

内容的提问来源于stack exchange,提问作者Sourabrata Bose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 11:02:59