javascript - 使回调等到函数在节点js中返回结果
问题描述
有一组文件需要处理。文件可能有不同的类型,因此有不同的函数进行处理。我希望遍历所有文件,收集日志,最后返回一个存储所有日志的变量。
编码:
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) 和 callback(null) 是异步的。callback(null) 首先完成,所有文件都被迭代,执行流程转到发送响应。与此同时,功能仍在执行中。
解决方法:还没想好。理想情况下,回调会在返回 null 之前等待函数返回它们各自的值(并完成执行)。
不能做什么:使用定时器让回调等待。正在处理的文件数量可以从 1 到数百,并且没有大小限制。处理每个文件可能花费的时间是未知的。
我已经尝试过:当函数完成执行时返回回调。将函数的返回值分配给变量(例如测试)并执行回调(测试)。没有一个工作。
解决方案
如果你想使用回调风格的代码,那么任何调用回调的函数本身都必须采用回调函数:
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
以帮助解开此代码。我发现它们更容易使用,尤其是在复杂的流量控制情况下。
推荐阅读
- android - 从 ViewModel 中的 SqlDelight 收集流时出现 java.lang.IllegalStateException
- arrays - 在 Go 中将字符串转换为数组
- javascript - 如何从 id 中获取值然后将其存储在另一个变量中
- c# - 无法解析此引用 Microsoft.Common.CurrentVersion.targets
- networking - 无法访问虚拟机本地主机上的 laravel 项目
- flutter - Flutter MouseRegion onExit 在浏览器边缘附近不起作用
- java - 简化的三元表达式
- rust - 为什么 TryInto 需要 T 中的 Copy 特征?
- github - 无需注册即可参与 Github
- html - 任何可能的方法来右对齐 Flexbox 中图像旁边的文本?