Сделайте обратный вызов, пока функция не вернет результат в узле - PullRequest
0 голосов
/ 25 апреля 2018

Существует массив файлов, которые нужно будет обработать.Файлы могут быть разных типов, поэтому есть разные функции, выполняющие обработку.Я ожидаю просмотреть все файлы, собрать журналы, находясь в нем, и в конце вернуть переменную, в которой хранятся все журналы.

Код:

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) завершается первым, все файлы повторяются, поток выполнения переходит к отправке ответа.Тем временем функции все еще выполняются.

Как это исправить: Не понял.В идеале, обратный вызов должен ждать, пока функции вернут свои соответствующие значения (и завершит выполнение), прежде чем вернуть ноль.

Что нельзя сделать: использование таймеров для ожидания обратного вызова.Количество обрабатываемых файлов может быть от 1 до сотен, и нет ограничений по размеру.Время, необходимое для обработки каждого файла, неизвестно.

То, что я пробовал: возврат обратных вызовов, когда функция завершает выполнение.Присвоение возвращаемого значения функции переменной (например, тест) и выполнение обратного вызова (тест).Ни один из них не работал.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2018

вы можете попробовать что-то вроде:

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); 
        }
    });
}
0 голосов
/ 25 апреля 2018

Если вы хотите использовать код в стиле обратного вызова, то любая функция, которая выполняет вызовы, которые принимают обратные вызовы, должна сама принять функцию обратного вызова:

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, чтобы помочь распутать этот код.Я обнаружил, что с ними значительно проще работать, особенно в сложных ситуациях управления потоком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...