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循环并没有真正改变这个特定示例中的任何内容,它只是一种防止与 Javascript 相关的错误的代码样式,而不是像 Java 这样的编程语言,只有变量的函数范围 - 所以在您的原始示例中,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 回答