需要处理一系列文件。文件可以是不同类型的,因此有不同的功能进行处理。我期望遍历所有文件,在其中收集日志,最后返回一个存储所有日志的变量。
代码:
var file_list = req.body.filelist.split(','); //array of filenames
var logs = []; //logs about the file processing will be stored here
//iteration through each file
async.forEach(file_list , function(file_from_list , callback){
if(file_is_type1(file_from_list)){
process_filetype_1(file_from_list);
callback(null);
}
else if(file_is_type1(file_from_list)){
process_filetype_2(file_from_list);
callback(null);
}
else{
logs.push("Unknown file type");
}
},function(error, result){
return res.status(200).send({message: import_log});
});
有两种不同的功能,在处理文件的逻辑上存在差异。这是一个复杂的代码,但运行顺畅,每个动作都在正确的时间执行。以下是其中一个函数的抽象:
function process_filetype_1(file_from_list){
async.auto({
dosth_1: function(callback) {
//logic implementation
},
dosth_2: ['dosth_1', function(callback) {
//logic implementation
}]
}, function(error, results) {
return results;
});
}
会发生什么:处理所有文件,但迭代内部的回调不会等待函数完成执行。因此,在文件处理完毕之前发送响应
为什么会发生:调用process_filetype_1(file_from_list)和回调(null)是异步的。 callback(null)首先完成,所有文件都被迭代,执行流程转到发送响应。同时功能仍在执行中。
如何解决这个问题:Haven没弄明白。理想情况下,回调会在返回null之前等待函数返回各自的值(并完成执行)。
无法做什么:使用计时器进行回调等待。正在处理的文件数量可以从1到数百,并且没有大小限制。处理每个文件可能需要的时间是未知的。
我尝试了什么:在函数执行完毕后返回回调。将函数的返回值赋给变量(例如test)并进行回调(测试)。两个人都没有工作。
答案 0 :(得分:2)
如果你想使用回调式代码,那么任何进行回调调用的函数必须本身采用回调函数:
function process_filetype_1(file_from_list, cb) {
async.auto({
dosth_1: function(callback) {
//logic implementation
},
dosth_2: ['dosth_1', function(callback) {
//logic implementation
}]
}, function(error, results) {
cb(error, results);
});
}
由于您的功能似乎没有做任何事情,您可以直接链接:
function process_filetype_1(file_from_list, cb) {
async.auto({
dosth_1: function(callback) {
//logic implementation
},
dosth_2: ['dosth_1', function(callback) {
//logic implementation
}]
}, cb);
}
另一种方法是将Promise系统与async
/ await
结合使用,以帮助解开此代码。我发现它们更容易使用,尤其是在复杂的流量控制情况下。
答案 1 :(得分:2)
if(file_is_type1(file_from_list)){
process_filetype_1(file_from_list, callback);
}
然后process_filetype_1看起来像:
function process_filetype_1(file_from_list, callback){
async.auto({
dosth_1: function(cb) {
//logic implementation
},
dosth_2: ['dosth_1', function(cb) {
//logic implementation
}]
}, function(error, results) {
if(error) { callback (error);
} else {
callback(results);
}
});
}