-1

Hello: i am new to nodejs and mocha. I trying to use module.exports to return a value from a callback function. However, its returning undefined. For simple cases it works though. Please help.

Result

  Module Export Example
    √ Test Case 1: Module
      Hello Node World!!! (*** this works - its a direct return ***)

    √ Test Case 2: Module
      undefined           (*** this fails - its from  a callback fn ***)

google.js

var requirejs = require('requirejs');       
requirejs.config({ baseUrl: '.', paths: {   }, nodeRequire: require });
describe('Module Export Example', function(){
    var mod;
    before(function(done){
        requirejs(['./googleModule'], 
            function(_mod) {
                mod = _mod;  
                done();
            });
    });  

    it('Test Case 1: Module', function(done){
        console.log(mod.get(done));
    });

    it('Test Case 2: Module', function(done){
        console.log(mod.google(done));
    });

});

googleModule.js

var request = require('request');
module.exports = {
    get: function(done){        
        var a = "Hello Node World!!!";
        return(done(), a);
    },   
    google: function(done){        
        var a = doCallback(function(){
            var b = "PRINT DATA: " + data.statusCode + ' ' + data.headers['content-type'];      
            return(done(), b);
        });
        return(done(), a);
    }
}       

function doCallback(callback, done){
    var options = {url: 'http://www.google.com', headers: {'Content-Type': 'text/html'}, encoding: null};
    request.get(options, function(err, res, body){
        var a  = callback(res, done);
        return (callback(), a); //???????
    });
}
4

1 回答 1

1

Because you say you are new to nodejs and mocha, I assume you didn't want to do anything fancy and simplified your code.

Result

  Module Export Example
Hello Node World!!!
    ✓ Test Case 1: Module
test
PRINT DATA: 200 text/html; charset=ISO-8859-1
    ✓ Test Case 2: Module (194ms)

test/test.js

let mod = require('../googleModule');

describe('Module Export Example', function(){

    it('Test Case 1: Module', function(){
        console.log(mod.get()); // this is synchronous, no done needed
    });

    it('Test Case 2: Module', function(done){
        mod.google(function(res) {
          console.log(res);
          done(); // this is asynchronous, so we need to tell mocha when we are done
        });
        console.log('test');
    });

});

googleModule.js

let request = require('request');

module.exports = {
  get: function() {
      let a = "Hello Node World!!!";
      return a;
  },
  google: function(callback) {
    let options = {url: 'http://www.google.com', headers: {'Content-Type': 'text/html'}, encoding: null};
    request.get(options, function(err, res, body) {
        var b = "PRINT DATA: " + res.statusCode + ' ' + res.headers['content-type'];
        callback(b);
    });
  }
}

I changed 2 major things to get it working.

  1. I removed require.js. You don't need to use that in node.js because a module loader is already included.

  2. In javascript there are synchronous and asynchronous functions. Synchronous functions are regular functions that you know from other programming languages like PHP or Java. However, javascript also has asynchronous functions. The difference is that the code inside an asynchronous function will be executed later and you can't expect it to return the value immediately. As an example, look at the output of your test and compare it to your code. As you can see, console.log('test'); gets printed BEFORE console.log(res), even though it is below the other one. To handle this, javascript makes use of callbacks (or Promises). A callback is like a way of telling the program where it should continue once the asynchronous function is finished. In your case, the HTTP-Request is asynchronous, so you need to tell your code to "wait" for it to finish and then print it. The done is used to tell mocha when the test is finished.

It's probably best if you read some articles about how asynchronous functions work.

于 2017-04-25T20:00:50.870 回答