0

希望得到一些帮助。我是 Nodejs 的新手,想知道是否可以删除这个自定义事件发射器。我正在使用包“ssh2-sftp-client”,代码运行良好,但我从节点控制台收到警告,说

(node:67350) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added to [Client]. Use emitter.setMaxListeners() to increase limit

但是我不确定在哪里清理事件,希望有人能给我一些建议。

async function executeFtpDownload() {
  try {
    await conn.connect({
      host: params.ftpHost,
      port: params.ftpPort,
      user: params.ftpUser,
      password: params.fptPassword,
    });

    const files = await conn.list("/home/bmw/autoline");
    const targetFiles = files.filter((file) => {
      return Object.values(targetFilesName).some(
        (targetName) => targetName === file.name
      );
    });

    const dirFiles = await Promise.all(
      targetFiles.map(async (file) => {
        await conn.downloadDir(
          `/home/bmw/autoline/${file.name}`,
          `./${params.LocalPath}/${file.name}`
        );

        const record = await conn.list(`/home/bmw/autoline/${file.name}`);
        const dateRecord = record.reduce((obj, item) => {
          const date = item.name.split("_")[0];
          if (obj[date]) {
            obj[date] = [...obj[date], item.name];
          } else {
            obj[date] = [item.name];
          }
          return obj;
        }, {});
        return {
          [file.name]: dateRecord,
        };
      })
    );

    const folder_list = dirFiles.reduce((acc, item) => {
      const key = Object.keys(item)[0];
      const record = item[key];
      return {
        ...acc,
        [key]: record,
      };
    }, {});

    const processUpload = await Promise.all(
      Object.entries(folder_list).map((folder) => {
        const folderName = folder[0];

        return Promise.all(
          Object.entries(folder[1]).map((subFolder) => {
            const subFolderName = subFolder[0];
            const files = subFolder[1];

            return Promise.all(
              files.map(async (file) => {
                const fileContent = fs.createReadStream(
                  `./${params.LocalPath}/${folderName}/${file}`
                );
                const remove_remote = `/home/bmw/autoline/${folderName}/${file}`;
                const remote = `/home/bmw/autoline/Uploaded${folderName}/${file}`;
                const localPath = `./${params.LocalPath}/${folderName}/${file}`;

                await s3
                  .putObject({
                    Body: fileContent,
                    Bucket: params.Bucket,
                    Key: `${folderName}/${subFolderName}/${file}`,
                  })
                  .promise();

                await conn.fastPut(localPath, remote);
                // await conn.delete(remove_remote);

                await fs.unlink(
                  `./${params.LocalPath}/${folderName}/${file}`,
                  function (err) {
                    if (err) throw err;
                    // if no error, file has been deleted successfully
                    console.log(`File ${file} deleted!`);
                  }
                );
              })
            );
          })
        );
      })
    );

    console.log("FTPDOWNLOAD DONE");
    conn.end();
    return folder_list;
  } catch (err) {
    conn.end();
    console.log("ERR executeFtpDownload:", err);

    return {
      statusCode: err.code,
      body: err.name,
    };
  }
}
4

1 回答 1

1

自两天以来运行相同的问题。

使用@supercharge/promise-pool救了我的命。

const { results,errors } = await PromisePool //Promise pool return an object containing these 2 properties where results = your promises responses as array
    .for(myArrayOfData) // Your data array for iteration that will pass each value to your process
    .withConcurrency(9) // Maximum amount of promises running at the same time
    .process(async currentObject=> { return  await myPromisedFunction(currentObject);}) // your promise execution

个人注意,因为它是由 SFTP 事件侦听器引起的警告,所以我设置withConcurrency()9因为我首先列出了创建1 个侦听器的远程文件夹中的所有文件,+ 9并发承诺获取所有文件内容的所有侦听器以及, 总共10是最大默认限制。

我的案例的完整样本:

client.list(CONFIG.sftp.folder).then(async (data) => {
                const { results,errors } = await PromisePool
                    .for(data)
                    .withConcurrency(9)
                    .process(async sftpFileObject => { let file = await readFileContent(client, CONFIG.sftp.folder, sftpFileObject); return file; })
                //Do some fun stuff with my results var containing my resolved data
                resolve('Successfully pulled all file content without warning!')
            }).then(() => {
                client.end();
            }).catch((err) => {
                client.end();
                console.error(err);
                reject(err)
            })
于 2021-01-28T10:54:58.170 回答