2017-04-24 31 views
1

你好:我是新的nodejs和摩卡。我正在努力從函數調用的返回值。即使(我認爲)我已經適當地使用了回調done(),它總是返回'未定義'。NodeJS,函數調用不返回undefined即使完成

在下面的例子中,我如何確保get()的返回值總是返回正確的值而不是'undefined'。在這個函數中,我使用requestJS模塊打開google.com並返回內容類型。但是,它目前返回未定義。

非常感謝!

更新後作出反饋:

  • 包括Test Case 3例如,爲實現Callback結果是:我現在可以根據需要打印數據。但是,我得到並告訴我要調用done()。我做錯了什麼?節點終端上

結果交運行

suite 
    PRINT DATA: 200 text/html; charset=ISO-8859-1 
    √ Test case 1 (607ms) 

    undefined (<< ****** how to return the correct value?**) 
    PRINT DATA: 200 text/html; charset=ISO-8859-1 
    √ Test case 2 (603ms) 

    PRINT DATA: 200 text/html; charset=ISO-8859-1 
    √ Test case 3 
    Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. 
    ... 

Google.js

var request = require('request'); 

describe('suite', function(){ 
    it('Tase case 1', function(done){ 
     var options = { url: 'http://www.google.com', headers: {'Content-Type': 'text/html'}};  
     request.get(options, function (err, res, body){ 
      console.log("PRINT DATA: " + res.statusCode + ' ' + res.headers['content-type']); 
      //do some stuff here       
      done(); 
     });   
    }); 

    it('Test case 2', function(done){ 
     console.log(get(done)); 
    }); 

    it('Test Case 3', function(){ 
     doCallback(callbackHandler); 
    }); 

}); 

function get(done){ 
    var options = { 
     url: 'http://www.google.com', 
     headers: {'Content-Type': 'text/html'}, 
     encoding: null 
    };  
    request.get(options, function(err, res, body){ 
     console.log("PRINT DATA: " + res.statusCode + ' ' + res.headers['content-type']); 
     //do some stuff here      
     return done(), res.headers['content-type'];   
    }); 
} 

function callbackHandler(data) { 
    console.log("PRINT DATA: " + data.statusCode + ' ' + data.headers['content-type']); 
} 

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

歡迎** **異步的奇妙世界!你不能那樣做;你需要使用回調或承諾。 – SLaks

+0

感謝@SLaks爲您提供指導。我現在爲原始問題添加了一個'callbacks'的例子。請參考「測試案例3」。我現在得到的數據,但我得到一個錯誤告訴調用done()。我不知道如何解決這個問題。也許我的方法是不正確的。請幫忙。 –

+0

您將兩個參數傳遞給僅接受一個參數的函數。你期望做什麼? – SLaks

回答

0

的一種可能的解決方案(使用回調)

var request = require('request'); 

describe('suite', function(){ 
    it('Test Case 3', function(done){ 
     doCallback(callbackHandler, done); 
    }); 

    it('Test Case: 3A', function(done){ 
     doCallback(function(data){ 
     console.log("PRINT DATA: " + data.statusCode + ' ' + data.headers['content-type']); 
     done();   
    }); 
});  

}); 

function callbackHandler(data, done) { 
    console.log("PRINT DATA: " + data.statusCode + ' ' + data.headers['content-type']); 
    done(); 
} 

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){   
     return callback(res, done); 
    }); 
} 

一個可能的解決方案(使用承諾)

var request = require('request'); 

describe('suite', function() { 
    this.timeout(10000); 
    it('Test Case 3', function() { 
     return doCallback() 
      .then(function (res) { 
       console.log(res.statusCode + " " + res.headers['content-type']); 
      }) 
      .catch(function(res){ 
       console.log(res); 
      }); 
    }); }); 

function doCallback() { 
    return new Promise(
     function (resolve, reject) { 
      var options = { url: 'http://www.google.com', headers: { 'Content-Type': 'text/html' }, encoding: null }; 
      request.get(options, function (err, res, body) { 
       if (err) 
        reject(err); 
       else 
        resolve(res); 
      }); 
     } 
    ); } 
+1

您應該返回promise,而不是在'it()'中使用'done'回調。 – SLaks

+1

不要將一個令人困惑的額外參數傳遞給回調函數,而應該使回調函數成爲測試中的匿名函數,並直接調用'done()'。 – SLaks

+0

hi @SLaks,完成。使用'callback'示例的匿名函數添加了新的測試用例。而且,對於'Promise'示例,即使我'返回'也可以工作。請讓我知道什麼是正確的返回聲明,以及爲什麼'返回然後'工作?非常感謝。 –