La función de la llamada de la cadena en nodejs

Lo que es el equivalente a la ventana[my_func_name] en nodejs? Estoy leyendo una cadena de stdin y si es un nombre de función que quiero ejecutar. Pensé global[my_func_name] podría funcionar, pero por desgracia no es así.

OriginalEl autor PaulK | 2013-10-17

3 respuestas

  1. 12

    Funciona muy bien

    global.foo = function foo () {
      console.log("foo was called");
    }
    
    process.stdin.on("data", function(input) {
    
      //don't forget to call .trim() to remove the \n
      var fn = input.toString().trim();
    
      //function exists
      if (fn in global && typeof global[fn] === "function") {
        global[fn]();
      }
    
      //function does not exist
      else {
        console.log("could not find " + fn + " function");
      }
    });
    
    process.stdin.resume();

    Salida

    foo
    foo was called
    bar
    could not find bar function

    Si esto es o no es una buena idea… bien, que es completamente distinta a la discusión.


    EDITAR — ≈18 meses más tarde… Sí, es un horrible idea para llamar a una función global como que.

    Diciendo que, aquí está uno forma de enfocar el problema de una manera mucho mejor. A continuación vamos a construir un poco de REPL (read-eval-print loop). Para entenderlo mejor, te voy a romper hacia abajo en un par de piezas.

    Primer lugar, queremos asegurarnos de que nuestros REPL espera a que el usuario presione entrar antes de intentar ejecutar sus órdenes. Para ello, vamos a crear un transformar la corriente que espera un "\n" personaje antes de enviar un line abajo de la tubería

    El siguiente código es escrito usando ES6. Si usted está teniendo problemas para encontrar una compatible entorno para ejecutar el código, le sugiero que visite babel.

    //line-unitizer.js
    import {Transform} from 'stream';
    
    class LineUnitizer extends Transform {
      constructor(delimiter="\n") {
        super();
        this.buffer = "";
        this.delimiter = delimiter;
      }
      _transform(chunk, enc, done) {
        this.buffer += chunk.toString();
        var lines = this.buffer.split(this.delimiter);
        this.buffer = lines.pop();
        lines.forEach(line => this.push(line));
        done();
      }
    }
    
    export default LineUnitizer;

    No demasiado colgó en LineUnitizer si eres nuevo en el procesamiento de flujo y no acaba de tener sentido. Este tipo de flujo de transformación es muy común. La idea general es esta: una vez que la tubería process.stdin en una corriente receptora, process.stdin se emiten los datos cada vez que el usuario presiona una tecla. Sin embargo, nuestro Repl (se implementa a continuación) no puede actuar en un comando hasta que el usuario ha terminado teclear el comando. LineUnitizer es la parte que espera a que el usuario pulse intro (que inserta un "\n" en la corriente) y, a continuación, las señales _transform que el comando está listo para ser enviado a repl para el procesamiento de!

    Veamos Repl ahora

    //repl.js
    import {Writable} from 'stream';
    
    class Repl extends Writable {
      _parse(line) {
        var [cmd, ...args] = line.split(/\s+/);
        return {cmd, args};
      }
      _write(line, enc, done) {
        var {cmd, args} = this._parse(line.toString());
        this.emit(cmd, args);
        done();
      }
    }
    
    export default Repl;

    Bueno, eso fue fácil! Qué hace tho? Cada vez que repl recibe una línea, se emite un evento con algunos argumentos. He aquí una forma visual de ver cómo un comando se analiza

    The user enters       emit event      args
    -------------------------------------------------------------
    add 1 2 3             "add"           ["1", "2", "3"]
    hens chocobo cucco    "hens"          ["chocobo", "cucco"]
    yay                   "yay"           []

    Ok, ahora vamos alambre todo junto para ver que funcione

    //start.js
    import LineUnitizer from './line-unitizer';
    import Repl         from './repl';
    
    process.stdin
      .pipe(new LineUnitizer())
      .pipe(
        (new Repl())
          .on("add", function(args) {
            var sum = args.map(Number).reduce((a,b) => a+b, 0);
            console.log("add result: %d", sum);
          })
          .on("shout", function(args) {
            var allcaps = args.map(s => s.toUpperCase()).join(" ");
            console.log(allcaps);
          })
          .on("exit", function(args) {
            console.log("kthxbai!");
            process.exit();
          }));

    Ejecutar

    $ node start.js

    Salida

    Líneas con prefijo > son la entrada del usuario. El > no serán visibles en su terminal.

    > add 1 2 3
    add result: 6
    > shout I can see it in your face!
    I CAN SEE IT IN YOUR FACE!
    > exit
    kthxbai!

    Si usted piensa que es impresionante, no estamos ni siquiera ha hecho todavía. Los beneficios de escribir nuestro programa de esta manera es que podemos actuar sobre los comandos independientemente de cómo llegar a nuestro programa.

    Considerar este commands.txt archivo

    add 100 200
    shout streams are the bee's knees
    exit

    Ahora ejecute algo como esto

    $ cat commands.txt | node start.js

    Salida

    300
    STREAMS ARE THE BEE'S KNEES
    kthxbai!

    Ok, así que es bastante fricken grandes. Ahora considere la posibilidad de que los comandos que puede venir de cualquier parte. Podría ser una base de datos de eventos, algo que a través de la red, una tarea CRON, etc. Porque todo está bien separados, se podría adaptar fácilmente este programa para aceptar una variedad de entradas con facilidad.

    Gracias, tienes razón. Solo pensé una función global será automáticamente añadido al objeto global como es el caso con el objeto de ventana.
    considere la posibilidad de aceptar esta respuesta si se resuelve el problema
    para lo que vale, he escrito muchos complejos node.js apps y nunca he (incluso ) tocó global
    Gracias, sin embargo hay un error en su código. Usted necesita para reemplazar la función de “existe” para: if (fn in global && typeof global[fn] === "function") { Su prueba falla en “fn” es una cadena, y se prueba si es una función.
    gracias por la captura de ese.

    OriginalEl autor user633183

  2. 1

    Escribir sus funciones en un archivo separado y exportación de los mismos y los utilizan con el nombre de referencia de que para llamar a ellos, Como

    //   functions.js
    var funcOne = function(){
                       console.log('function ONE called')
                  }
    module.exports={
        // name_exported : internal_name
        funcOne : funcOne
    }

    Uso de la función definida en functions.js en index.js :

    //   index.js
    var methods = require('./functions.js')   //path to functions.js
    methods['funcOne']()

    De SALIDA :

    > node index.js
    > function ONE called

    OriginalEl autor Rupinder Singh

  3. 0
    var theTests = require('./tests'); 
    //@TODO CaseID should be caseId
    var CaseID = 5678;
    //use dynamic functions
    var functionName = 'theTests.TEST_' + CaseID;
    var functionString = String('TEST_' + CaseID);
    
    var check = eval( 'typeof ' + functionName ); //bad
    if ( check == 'function' ) {
        //run the function
        //testResult = eval( functionName ); nope
        testResult = theTests[functionString](); //yep :)
        console.log(testResult);
    }
    else {
        console.log( 'No test functions for ' + CaseID );
    }

    en este ejemplo en tests.js
    se busca…

    TEST_5678: function(){
         return some thing;
    },

    OriginalEl autor taggartJ

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *