Почему функция zlib inflate не работает в правильном порядке в файле node.js?

Я новичок в Stackru. Сейчас я работаю над программой node.js. Входными данными является поток данных, содержащий несколько блоков данных (также заархивированных по алгоритму DEFLATE), соединенных вместе. Моя цель - использовать INFLATE, чтобы восстановить блоки данных и расположить их в правильном порядке.

Моя проблема в том, что когда я использую цикл while для извлечения блоков данных, извлеченные данные находятся не в порядке ввода. Зачем?

while (initPointer < totalLength) {
    ...
    console.log('Extracting '+rawLengthBuf.readUInt32LE(0));

    ...

    zlib.inflate(dataBuf, function(err, data) {
        if (!err) {
            console.log('Extracted '+data.length);
        }
    });
}

Выход:

Extracting 18876
Extracting 15912
Extracting 10608
Extracted 15912
Extracted 10608
Extracted 18876

Пожалуйста, прости меня, что я не могу описать ситуацию очень ясно. Благодарю.

2 ответа

Решение

Используйте Async.js. Ниже приведены шаги для синхронной работы вашего кода с использованием async.js.

Я столкнулся с подобной проблемой и решил ее, используя шаги ниже. Я заменил свою функцию на вашу. Он должен работать. Вы просто попробуете, документация встроена, чтобы вы поняли код.

/*
 * need an array to run all queries one by one in a definite order
 */
var arr = [];

while (initPointer < totalLength) {
    console.log('Extracting '+rawLengthBuf.readUInt32LE(0));
    arr.push(dataBuf)
}


/*
 * Callback function for initiation of waterfall
 */
var queue = [
    function(callback) {
        // pass the ref array and run first query by passing starting index - 0
        callback(null, arr, 0)
    }
];

/*
 * Object to store result of all async operation
 */
var finalResult = {};

/*
 * Generic Callback function for every dynamic query
 */
var callbackFunc = function(prevModelData, currentIndex, callback) {
    //current file/data
    zlib.inflate(arr[currentIndex], function(err, data) {
        if (!err) {
            console.log('Extracted '+data.length);
        } else {
            // console.log(result)
            finalResult[arr[currentIndex]] = data
            //call next element in queue
            callback(null, data, currentIndex + 1)
        }
    });
}

/*
 * Add callback function for every dynamic query
 */

while (initPointer < totalLength) {
    ...
    console.log('Extracting '+rawLengthBuf.readUInt32LE(0));

    ...

    queue.push(callbackFunc)

}


/*
 * Run all dynamic queries one by one using async.js waterfall method
 */
async.waterfall(queue, function (err, result) {
    console.log('finish', finalResult)
});

Асинхронный zlib методы выполняют свою работу в пуле потоков, поэтому каждый раздув может выполняться параллельно. То, какая инфляция заканчивается первым, зависит от ряда факторов (например, алгоритм планирования ЦП), поэтому вы не можете принять конкретный порядок при вызове zlib.inflate() в такой петле.

Другие вопросы по тегам