如何将参数传递给自执行的module.exported匿名节点函数?

时间:2016-07-25 17:45:32

标签: javascript node.js

我试图用一个带有来自另一个nodejs文件的参数对象来调用一个自动执行的匿名函数与一个参数对象一起导出,这个函数需要带有匿名函数的文件并传递参数对象,如下所示:

fileThatCallsTheAnonymousSelfExecutingFunction: `

var parameters = {
    filename: "UsernamesAndQueues",
    headers: ["username", "password", "queue"],
    columns: ["ascii", "ascii", "ascii"],
    wordLength: 25,
    count: 100
};

var generateData = require("../scripts/generateData.js")(parameters);

generateData.js:

// if the function does not call itself in this file, i can pass the
// arguments normally, and it prints out the expected options.

module.exports = (function (options) {

    console.log("Hello %s", JSON.stringify(options));
    options = options || { 
                            "headers": ["username", "password", "queueName"], 
                            "columns": ["ascii", "ascii", "ascii"], 
                            "wordLength": 26, 
                            "count": 101
                        };

    console.log("Current options are: %s", JSON.stringify(options));
    // I just want to know what the arguments are for now, so I interrupt
    process.exit();
    // i just want for the moment to print out the options object
    // later on, i would like to use the options as i would parse arguments ??? options[0], options[1], options[2] etc. 

    // rest of the file that really needs the function arguments 
    console.log("something");
    var fs = require('fs'),
        generate = require('csv-generate'),
        filename = "UsernamesAndQueues",
        csvfilestream = fs.createWriteStream("../data/" + "generated" + filename + ".csv", { flags: 'w' }),
        error = fs.createWriteStream(__dirname + '/node.error.log', {flags: 'w'}),
        // CSV generator (read command line arguments, create with defaults, making filename required)
        generator = generate({
            header: options.headers, 
            columns: options.columns,
            max_word_length: options.wordLength,
            length: options.count
        });

        // Redirect stdout / stderr to file
        process.stdout.write = csvfilestream.write.bind(csvfilestream);
        process.stderr.write = error.write.bind(error);

        // Handle Uncaught Exceptions / Errors
        process.on('uncaughtException', function(err){
            console.error((err && err.stack) ? err.stack : err);
        });

        // Output CSV to stdout stream -> to file
        generator.pipe(process.stdout);
})(arguments[0]);

我问的是处理传递给函数的参数的正确方法是什么?我想这样做,以便从cmd行调用它,并使用(可选的)命令行参数。在我弄清楚如何这样做之后,我可以进一步使用参数解析器。

如果您有其他建议实现可以作为命令行脚本(node generateData.js --headers ["param1", "param2", "param3"] --columns ["ascii", "ascii", "ascii"] --wordLength 25 --count 100运行的节点脚本(函数),并且作为必需模块将模块导出到另一个并传递上面的参数对象( var generateData = require("../scripts/generateData.js")(parameters);),请写一个诙谐的回复!

其他问题:我做得对,我做错了什么,我能阅读什么,在哪里可以更好地掌握这些概念?我看过Mozilla Dev和其他一些网站。我发现了有关带参数的自执行匿名函数的事情,但没有从外部文件中调用过。也许我甚至都没有找到合适的东西......

稍后编辑: 我已经尝试导出该函数并从另一个文件中调用它。这是简单的方法。

scriptThatRequiresTheExportedModuleAndCallsItWithParameters(参数)的.js

var parameters = {
  headers: ["username", "password", "queue"],
  columns: ["ascii", "ascii", "ascii"],
  word_length: 25,
  count: 100
};
// this works
var generateUsernames = require('../scripts/generateData.js')(parameters);

generateData.js

// this works, just exporting the function, without self-executing (calling)
// i call the function (providing arguments) from the other file requiring it
module.exports = function (options) {
    console.log("Hello %s", JSON.stringify(options));
    options = options || { 
                            "headers": ["username", "password", "queueName"], 
                            "columns": ["ascii", "ascii", "ascii"], 
                            "wordLength": 26, 
                            "count": 101
                        };
    console.log("Current options are: %s", JSON.stringify(options));
    // exiting, because, for now, i just want to know what the arguments (options) are
    process.exit();
    console.log("something");
    var fs = require('fs'),
        generate = require('csv-generate'),
        filename = "UsernamesAndQueues",
        csvfilestream = fs.createWriteStream("../data/" + "generated" + filename + ".csv", { flags: 'w' }),
        error = fs.createWriteStream(__dirname + '/node.error.log', {flags: 'w'}),

    // CSV generator (read command line arguments, create with defaults, making filename required)
    generator = generate({
        header: options.headers, 
        columns: options.columns,
        max_word_length: options.wordLength,
        length: options.count
    });

    // Redirect stdout / stderr to file
    process.stdout.write = csvfilestream.write.bind(csvfilestream);
    process.stderr.write = error.write.bind(error);

    // Handle Uncaught Exceptions / Errors
    process.on('uncaughtException', function(err){
        console.error((err && err.stack) ? err.stack : err);
    });

    // Output CSV to stdout stream -> to file
    generator.pipe(process.stdout);
};

2 个答案:

答案 0 :(得分:3)

您没有合适的结构。自我执行(技术上是“内联调用”)立即执行,而不是稍后当使用您的模块的人决定调用它时。看来你只想导出一个常规函数,根本不需要自执行部分。然后,模块的调用者将根据您的使用模式显示参数。

改为:

module.exports = function (options) {

    console.log("Hello %s", JSON.stringify(options));
    options = options || { 
                            "headers": ["username", "password", "queueName"], 
                            "columns": ["ascii", "ascii", "ascii"], 
                            "wordLength": 26, 
                            "count": 101
                        };

    console.log("Current options are: %s", JSON.stringify(options));
    process.exit();
    // i just want for the moment to print out the options object
    // later on, i would like to use the options as i would parse arguments ??? options[0], options[1], options[2] etc. 

    // rest of the file that really needs the function arguments 
    console.log("something");
    var fs = require('fs'),
        generate = require('csv-generate'),
        filename = "UsernamesAndQueues",
        csvfilestream = fs.createWriteStream("../data/" + "generated" + filename + ".csv", { flags: 'w' }),
        error = fs.createWriteStream(__dirname + '/node.error.log', {flags: 'w'}),
        // CSV generator (read command line arguments, create with defaults, making filename required)
        generator = generate({
            header: options.headers, 
            columns: options.columns,
            max_word_length: options.wordLength,
            length: options.count
        });

        // Redirect stdout / stderr to file
        process.stdout.write = csvfilestream.write.bind(csvfilestream);
        process.stderr.write = error.write.bind(error);

        // Handle Uncaught Exceptions / Errors
        process.on('uncaughtException', function(err){
            console.error((err && err.stack) ? err.stack : err);
        });

        // Output CSV to stdout stream -> to file
        generator.pipe(process.stdout);
};

P.S。为什么在函数中间有一个process.exit();,其余部分未使用?

如果您希望能够从命令行或作为其他人调用的常规模块使用它,那么您可以创建另一个小模块来获取命令行参数,加载此模块并调用它。我不清楚你希望命令行参数如何工作,但一般结构是这样的:

// command line module processing module
// gendata.js

// load the generateData module
var gData = require('./generateData.js');

var options = {};
// some code here to process the command line arguments in process.argv
// into the options object

// call the other module with the command line arguments in the options object
gData(options);

然后,您可以从命令行执行此操作:

node gendata.js arg1 arg2 arg3

答案 1 :(得分:1)

正如jfriend00指出的那样," ... [你的代码]立即执行,而不是稍后当使用你的模块的人决定调用它时。"您需要将module.exports的函数分配给require,以便以预期的方式使用它。

使用节点generateData.js [参数列表]"获取"命令行您正在寻找的行为,您可以添加一个条件来检查上下文是否为CLI,然后调用该函数,如果不是则导出:

var fancyFn = function(options) {
  ...
};
if (require.main === module) {
  fancyFn(arguments[0]);
} else {
  module.exports = fancyFn;
}