0

ねえ、

node.js とそのコールバック メカニズムを試しています。そして今、そのような匿名のコールバックにデータをオーバーハンドする方法を考えています:

var fs = require('fs');

for (var i = 0; i < 4; i++) {
    console.log('Outer: ' + i);
    fs.readFile('/etc/hosts', 'ascii', function(err, data) {
        console.log('Inner: ' + i);
    });
}

i への内部呼び出しが常に 4 を返す理由を理解しています。しかし、その特定の readFile-callback 関数にいくつかの変数を指定するにはどうすればよいでしょうか (内側の i が外側の i の値を持つように)。コールバック関数がコンシューマーとして機能するキュー メカニズムを想像することもできますが、ノードの初心者としてベスト プラクティスをお願いしたいと思います。どうもありがとう、

メカコ

4

1 に答える 1

1

純粋なJavascriptを使用する場合(つまり、非同期などのライブラリを使用しない場合):

var fs = require('fs');

var i,
    reader = function (i) {
        return function (err, data) {
            console.log('Inner: ' + i);
        }
    };

for (i = 0; i < 4; i++) {
    console.log('Outer: ' + i);
    fs.readFile('/etc/hosts', 'ascii', reader(i));
}

または、あるいは、

var fs = require('fs');

var i;

for (i = 0; i < 4; i++) {
    console.log('Outer: ' + i);
    fs.readFile('/etc/hosts', 'ascii', function (i, err, data) {
        console.log('Inner: ' + i);
    }.bind(null, i));
}

var i;(宣言をループの外に移動してforも、この特定の例では実際には何も変更されません。変数の関数スコープのみを持つJavaのようなプログラミング言語とは対照的に、Javascriptに関連するバグを防ぐためのコードスタイルにすぎません。これは、元の例でiは、forforループだけでなく、モジュール全体に対して宣言されています)。

別のアプローチは、次のようなライブラリを使用することasyncですunderscore

var _ = require('underscore'),
    async = require('async'),
    fs = require('fs');

async.parallel(_.map(_.range(0, 4), function (i) {
    return async.waterfall.bind(null, [
        fs.readFile.bind(null, '/etc/hosts', 'ascii'),
        function (data, callback) {
            console.log("Inner: " + i);
            callback();
        }
    ]);
}, function (err) {
    if (err) {
        console.log("Some read attempt failed");
    } else {
        console.log("Done reading");
    }
});
于 2012-08-02T11:41:32.087 に答える