0

次のような配列に一時的に書き込んでいる node.js ストリームがあります。

var tempCrossSection = [];

stream.on('data', function(data) {
    tempCrossSection.push(data);
});

次に、その配列のデータを定期的に取得 (およびクリア) し、次のように処理を行います。

var crossSection = [];

setInterval(function() {
    crossSection = tempCrossSection;
    tempCrossSection = [];

    someOtherFunction(crossSection, function(data) {
        console.log(data);
    }
}, 30000);

問題は、ストリームが配列に書き込まれる順序と、ストリーム レートが増加したり、someOtherFunction コールバックに時間がかかりすぎたりするときに発生する setInterval コールバックの数で、奇妙な動作が発生することです。

ストリームがデータを配列に (順番に) 正しく書き込み、データ処理が setInterval コールバックごとに 1 回実行されるように、これをどのように実装する必要がありますか。

4

1 に答える 1

1

コードにはいくつかの問題があります。まず第一に、あなたは多くの状態に共有しています。たとえば、crossSection は無名の Interval 関数でのみ定義する必要があります。「crossSection」がクロージャーとして定義されているのはなぜですか? someOtherFunction が長時間実行されると、ある種の競合状態に陥る可能性があります。

var source = [];

stream.on('data', function(data) {
    source.push(data);
});

setInterval(function() {
    var target = source;
    source = [];

    someOtherFunction(target, function(data) {
        console.log(data);
    }
}, 30000);

someOtherFunctionにアクセスできる場合は、このようにすべてを書き直します

var source = [];

stream.on('data', function(data) {
    source.push(data);
});

setInterval(function() {
    var processing = true;

    while (processing) {
        var elem = source.shift();
        someOtherFunction(elem, function(data) {
            console.log(data);
        });
        processing = checkForBreakConditionAndReturnFalseIfBreak();
    }
}, 30000);

それでも、要素の数が多すぎてsomeOtherFunctionsに時間がかかりすぎると、問題が発生する可能性があります。だから私はおそらくこのようなことをするでしょう

var source = [];
var timerId = 0;

stream.on('data', function(data) {
    source.push(data);
});

function processSource() {
    clearTimeout(timerId);
    var processing = true;

    while (processing) {
        var elem = source.shift();
        someOtherFunction(elem, function(data) {
            console.log(data);
        });
        processing = checkForBreakConditionAndReturnFalseIfBreak();
    }
    setTimeout(processSource, calcTimeoutForNextProcessingDependentOnPastData());
};

setTimeout(processSource, 30000); //initial Timeout
于 2013-04-03T08:33:27.953 に答える