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

Node.js:如何在Promise.all循环中向Promise传递参数?

解决Promise参数传递问题

问题根源

你当前的代码中,p1和p2是在for循环外部创建的Promise实例,Promise的执行器函数(new Promise里的回调)在创建时就会立即执行。所以后续循环中修改folder、subfolder、pastsearch的值,不会影响已经创建好的Promise——它们只会使用最初的变量值执行一次,无法响应循环中的参数变化。

解决方案

把p1和p2改成接受参数的函数,每次循环迭代时调用函数生成新的Promise实例,这样就能传入当前循环的folder、subfolder、pastsearch参数。

修改后的完整代码

const fs = require('fs');
const readline = require('readline')

const task_id = 1;
const myarray = [6567, 50105, 67637, 293697];
const myfiles = ['file_1.txt', 'file_2.txt'];

// 清空目标文件(补全路径)
fs.writeFile('/pathtofile/plain_round' + task_id + '.txt', '', () => console.log('plain file cleared'));
fs.writeFile('/pathtofile/round' + task_id + '.txt', '', () => console.log('count file cleared'));

// 封装成函数,接收参数返回Promise
function createSearchPromise(folder, subfolder, pastsearch, filePath) {
  return new Promise((resolve, reject) => {
    let yesnon = "non";
    const readStream = readline.createInterface({
      input: fs.createReadStream(`/pathtofile/round_${task_id}/threehundred_${folder}/${subfolder}/${filePath}`, 'utf8')
    });

    readStream.on("line", (line) => {
      if (line == pastsearch) {
        yesnon = "yes";
      }
    });

    readStream.on('end', () => readStream.destroy());
    readStream.on("close", () => resolve({ yesnon }));
    // 添加错误处理
    readStream.on("error", (err) => reject(err));
  });
}

// 简化计数函数,避免每次循环重复创建
function countYes(results) {
  return results.filter(({ yesnon }) => yesnon === "yes").length;
}

for (let h = 0; h < 3; h++) {
  const folder = 1 + h; // 直接计算当前值,避免全局变量修改
  const subfolder = 1 + h;
  const pastsearch = myarray[h];

  // 每次循环调用函数生成新的Promise
  const p1 = createSearchPromise(folder, subfolder, pastsearch, myfiles[0]);
  const p2 = createSearchPromise(folder, subfolder, pastsearch, myfiles[1]);

  Promise.all([p1, p2])
    .then((results) => {
      const output = results.map(({ yesnon }) => yesnon).join(' ');
      fs.appendFileSync(`/pathtofile/plain_round${task_id}.txt`, `${output}\n`, 'utf8');

      const yesCount = countYes(results);
      fs.appendFileSync(`/pathtofile/round${task_id}.txt`, `${yesCount}\n`, 'utf8');
    })
    .catch((err) => console.error('搜索出错:', err)); // 添加错误捕获
}

关键修改说明

  1. Promise封装为函数:createSearchPromise接收需要的参数,每次调用都会生成新的Promise,确保使用当前循环的参数值。
  2. 避免全局变量修改:循环内直接计算folder和subfolder的值,不依赖全局变量的累加,逻辑更清晰。
  3. 优化计数逻辑:把countValues改成通用的countYes函数,避免在循环内重复定义函数。
  4. 添加错误处理:给readStream添加error事件监听,Promise添加catch,避免静默失败。
  5. 模板字符串优化路径:使用模板字符串替代字符串拼接,代码更易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:45:37