2

私は非同期JavaScriptの経験があまりありません。コマンドの量をハードコーディングしたり、evalを使用したりせずに、コマンドを呼び出すにはどうすればよいですか?

var commands = [
    // command 1: result: 0, stdout: ""
    function (stdin, callback) {
        callback(0, "");
    },
    // command 2: result: 1, stdout: ""
    function (stdin, callback) {
        callback(1, "");
    },
    // command 3: result: 0, stdout: ""
    function (stdin, callback) {
        callback(0, "");
    },
    // ...
];

var stdin = "foo";
var end = function (result, stdout) {
    console.log(result);
    console.log(stdout);
};

commands[0](stdin, function (result, stdout) {
    commands[1](stdout, function (result, stdout) {
        commands[2](stdout, end);
    });
});
4

2 に答える 2

1

最終的な答え:

コマンド配列を調べるために再帰を使用しています。ループ関数にコマンドの配列と呼び出される最後のコールバックを渡します(4番目のオプションのパラメーターとして、ループを開始する配列のインデックスを渡すこともできます。デフォルトはゼロです)。

var commands = [
    // echo foo
    function (stdin, callback) {
        callback(0, "foo");
    },
    // touppercase
    function (stdin, callback) {
        callback(1, stdin.toUpperCase());
    }
];

var stdin   = "",
    loop    = function(commands, lastCallback, stdin, startIndex) {
        (function insideLoop(i, stdout) {
            commands[i](stdout, (i + 1 < commands.length) ? function(result, stdout){ insideLoop(i + 1, stdout); } : lastCallback); 
        })(startIndex || 0, stdin);
    },
    end     = function (result, stdout) {
        console.log(stdout);
    };

loop(commands, end, stdin);

コード例

于 2012-11-08T17:01:03.157 に答える
0

これらの関数を非同期で実行するには、呼び出しの合間に、ブラウザー(または実際には任意の実装)が他の処理(クリーンアップ、リフローなど)を実行できるようにすることで関数を呼び出す方法が必要です。

これは.setTimeout、ブラウザーまたは.nextTicknodejSで実行できます。

function runAsync( list ) {
    (function _worker( method ) {
        method();

        if( list.length ) {
            setTimeout(function() {
                _worker( list.shift() );
            }, 100);
        }
    }( list.shift() ));
}

これは次のように呼ばれます

runAsync( commands );

そして、次の配列エントリ(関数と見なされます)を取得して実行します。その後、そのエントリにさらに要素があるかどうかを確認し、ある場合は、次を取得して次の関数を呼び出します。これは、通話と100ミリ秒の遅延の中で発生setTimeoutます。ここでは100msを選択しました。これは、人間の蜂が「減速」や「遅れ」を認識しない時間枠であるためです。

于 2012-11-08T16:45:58.407 に答える