【问题标题】:NodeJS, function call not returning undefined even after doneNodeJS,即使完成后函数调用也不会返回未定义
【发布时间】:2017-04-24 21:49:16
【问题描述】:

你好:我是 nodejs 和 mocha 的新手。我正在努力处理函数调用的返回值。即使(我认为)我已经适当地使用了回调 done(),它总是返回“未定义”。

在以下示例中,我如何确保 get() 的返回值始终返回正确的值而不是“未定义”。在这个函数中,我使用 requestJS 模块打开 google.com 并返回内容类型。但是,它目前返回 undefined。

非常感谢!

更新的帖子反馈:

  • 包含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); 
    }); 
}

【问题讨论】:

  • 欢迎来到 async 的美妙世界!你不能那样做;你需要使用回调或承诺。
  • 感谢@SLaks 的指导。我现在在原始问题中添加了callbacks 的示例。请参考Test Case 3。我现在正在获取数据,但我收到一个错误,告诉我调用 done()。我不知道如何解决这个问题。也许我的方法是不正确的。请帮忙。
  • 您将两个参数传递给一个只接受一个参数的函数。你希望它做什么?
  • @SLaks,我完全被卡住了。我也尝试删除第二个参数。问题似乎出现在doCallback() 内部,其中有对request.get(...) 的调用。执行此操作的正确方法是什么?再次感谢。
  • 你好@SLaks,它可能与节点有关吗?我正在使用Node v7.9.0requestjs v2.81.0。我使用node v 6.9.0Run Kit 上尝试了它(在删除摩卡元素后),request.get(...) 被正确调用。

标签: node.js mocha.js requestjs


【解决方案1】:

一种可能的解决方案(使用回调)

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); 
    }); 
}

一种可能的解决方案(使用 promise)

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);
            });
        }
    ); }

【讨论】:

  • 你应该返回 promise 而不是在 it() 中使用 done 回调。
  • 不要将一个令人困惑的额外参数传递给回调,您应该在测试中将回调设为匿名函数并直接调用done()
  • 嗨@SLaks,完成。为callback 示例添加了使用匿名函数的新测试用例。而且,对于Promise 示例,即使我return then 也可以使用。请让我知道什么是正确的退货声明以及为什么return then 有效?非常感谢。
  • return then 没有意义;您正在返回一个未定义的变量。您应该添加'use strict'; 来防止这种情况。您需要从测试方法中返回承诺本身;请参阅文档。你的错误回调也是错误的;你根本不应该有那个。
  • 你的错误回调实际上并没有做任何事情(你没有调用console.error),你没有理由拥有一个(你没有任何有意义的方法来处理错误) .如果你返回一个失败的 Promise 给测试运行器,它会显示错误。
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多