async.series未执行第二个函数:Node.js顺序调用日志下载与归类功能异常
问题根因
- 你传入
async.series的第一个任务函数从未调用callback参数,async库感知不到第一个任务已完成,因此永远不会触发第二个任务执行 - 你封装的
writeFiles、sort都是异步函数,原代码调用时没有等待异步逻辑执行完成,就算调用了callback也会出现逻辑时序错误 sort函数混用回调式API和async/await语法,导致函数返回时内部的文件读取、移动逻辑还未执行完成,就算顺序调用也会出现下载没完成就开始移动的异常- 额外小问题:
writeFiles里start函数的console.log('done')写在return语句之后,永远不会执行,需要的话可以移到return前面
修复方案
1. 修复sort函数的异步逻辑
把fs API替换为promise版本,避免回调和async/await混用,保证函数返回时所有文件移动操作已完成
const testFolder = './logs/'; const fs = require('fs').promises; // 改用promise版本的fs API const path = require("path"); var directory = path.join(__dirname,'/logs/'); async function sort (){ console.log('inside sort function sorting file'); const files = await fs.readdir(directory); if(files){ console.log('filesss') } else { console.log('no filesss') } // 等待所有文件移动操作完成 await Promise.all(files.map(async file => { let fileFolder = file.split('-')[0]; var folder = fileFolder.replace('.', ""); var dir = path.join(directory, folder); // 判断文件夹是否存在 const dirExists = await fs.access(dir).catch(() => false); if (!dirExists){ await fs.mkdir(dir, {recursive: true}); } const currentPath = path.join(directory, file); const destinationPath = path.join(directory, folder, file); await fs.rename(currentPath, destinationPath); console.log("Successfully moved the file!", file); return destinationPath; })); } module.exports = sort;
2. 修复index.js的执行逻辑
你已经用了async函数,不需要额外引入async库做串行控制,直接用原生await按顺序调用即可,代码更简洁易读
'use strict'; // Initialize constants // 不需要引入async库了 const writeFiles = require('./webdavConnect2'); const sort = require('./sortingFiles'); // Initialize the program let program = require('commander'); // Initialize the version program.version('0.5.0'); program .command('say') .description('Batch command that can be used to zip, upload, import, and re-index for a given site import.') .action(async function () { // 回调函数加async标识 try { console.log('开始下载日志文件'); await writeFiles(); // 等待下载全部完成 console.log('下载完成,开始归类移动文件'); await sort(); // 等待移动全部完成 console.log('END'); } catch (err) { throw err; } }); // Parse the command-line arguments program.parse();
可选:保留async.series的写法
如果你有需求必须用async.series,写法如下:
program .command('say') .description('Batch command that can be used to zip, upload, import, and re-index for a given site import.') .action(function () { async.series([ async function(callback) { try { console.log('inside webdav function'); const directory = await writeFiles(); callback(null, directory); } catch (err) { callback(err); } }, async function(callback) { try { console.log('inside sort function'); const destinationPath = await sort(); callback(null,destinationPath); } catch (err) { callback(err); } } ], function(asyncErrorObj) { if (asyncErrorObj !== null) { throw asyncErrorObj; } console.log('END'); }); });
内容的提问来源于stack exchange,提问作者sonal
相关产品推荐
相关产品推荐

