为什么zlib inflate函数在node.js中的工作顺序不正确?

时间:2014-12-31 10:10:26

标签: node.js blocking zlib deflate inflate

我是Stackoverflow的新手。我现在正在研究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 个答案:

答案 0 :(得分:1)

异步zlib方法在线程池中工作,因此每个inflate 可以并行执行。首先完成哪个膨胀取决于许多因素(例如CPU调度算法),因此当您在类似循环中调用zlib.inflate()时,您无法假定特定顺序。

答案 1 :(得分:1)

使用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)
});