Javascript 节点函数返回';未定义';在请求以所需的返回值完成之前

Javascript 节点函数返回';未定义';在请求以所需的返回值完成之前,javascript,node.js,jasmine,jasmine-node,Javascript,Node.js,Jasmine,Jasmine Node,我知道Node是关于回调的。随着我对Jasmine和Node的更多了解,在创建Jasmine测试时,我试图记住这一点 我使用jasmine节点编写了一个非常基本的测试,它应该获得一个HTML页面,使用'cheerio'加载和解析返回的HTML,并提取HTML元素的内容。我的测试应该是验证“cheerio”返回的文本的准确性 我发现我正在测试的函数在请求完成之前返回“undefined”。您可以在测试的输出中看到这一点。测试报告失败后,您将看到console.log输出 我曾尝试使用回调来解决这个

我知道Node是关于回调的。随着我对Jasmine和Node的更多了解,在创建Jasmine测试时,我试图记住这一点

我使用jasmine节点编写了一个非常基本的测试,它应该获得一个HTML页面,使用'cheerio'加载和解析返回的HTML,并提取HTML元素的内容。我的测试应该是验证“cheerio”返回的文本的准确性

我发现我正在测试的函数在请求完成之前返回“undefined”。您可以在测试的输出中看到这一点。测试报告失败后,您将看到console.log输出

我曾尝试使用回调来解决这个问题,我也看到过关于使用库(如“async”)的帖子。我尝试使用beforeach()存储测试数据

我还没有找到正确的食谱,我需要一些帮助

index.html 模块1-spec.js(我的测试) 失败测试的输出
故障:
1) 模块1应该从页面获取数据
信息:
预期未定义为“此处有标题”。
堆栈跟踪:
错误:预期未定义为“此处标题”。
在空。(c:\test\spec\module1-spec.js:14:22)
以0.011秒完成
2次测试,2次断言,1次失败,0次跳过
使用数据执行回调:标题在这里
返回数据:标题在这里
此函数将数据返回到他的匿名函数=>function(err,data),因为此方法是异步的,我认为您应该重新显示您的测试以支持异步方法,并向testJq函数添加回调参数。

已重构,现在似乎可以工作了 我重新构建了我的模块和测试,使它们至少通过了测试。我不确定这是否是编写模块的最佳方式,但这是朝着正确方向迈出的一步,并演示了一种编写Jasmine测试的方法,该测试检查异步请求返回的值

我的许多变化都是从

我在这里有很多新手动作吗?有没有专业人士建议修复任何问题

模块1.js 模块1-spec.js
<!doctype html>
<html>
<body>
<span class="title">Title Goes Here</span>
</body>
</html>
var request = require('request');
var cheerio = require('cheerio');

exports.whoAmI = function () {
    'use strict';
    return "module1";
};

exports.testJq = function () {
    'use strict';
    var tipsotext = function (callback) {
        var output;
        request.get('http://localhost/test-test/index.html', function optionalCallback(err, httpResponse, body) {
            var $ = cheerio.load(body);
            output = $('.title').text();
            console.log("Executing callback with data: " + output);
            callback(null, output);
        });
    };

    tipsotext(function (err, data) {
        console.log("Returning with data: " + data);
        return data;
    });
};
var module1 = require("../src/module1.js");

describe("module1", function () {
    'use strict';

    it("should identify itself with whoAmI", function () {
        var test;
        test = module1.whoAmI();
        expect(test).toBe("module1");
    });
    it("should get data from the page", function () {
        var test;
        test = module1.testJq();
        expect(test).toBe("Title Goes Here");
    });
});
Failures:

  1) module1 should get data from the page
   Message:
     Expected undefined to be 'Title Goes Here'.
   Stacktrace:
     Error: Expected undefined to be 'Title Goes Here'.
    at null.<anonymous> (c:\test-test\spec\module1-spec.js:14:22)

Finished in 0.011 seconds
2 tests, 2 assertions, 1 failure, 0 skipped

Executing callback with data: Title Goes Here
Returning with data: Title Goes Here
  tipsotext(function (err, data) {
    console.log("Returning with data: " + data);
    return data;
});
var request = require('request');
var cheerio = require('cheerio');
var title;
exports.whoAmI = function () {
    'use strict';
    return "module1";
};

exports.extractTitleFromBody = function (callback) {
    'use strict';
    request({
        url: 'http://localhost:63342/browserify-test/index.html', //URL to hit
        method: 'GET'
    }, function(error, response, body){
        if(error) {
            title = error;
        } else {
            var $ = cheerio.load(body);
            title = $('.title').text();
        }
        if (typeof callback === "function") {
            callback();
        }
    });
};
exports.getTitle = function () {
    'use strict';
    return title;
};
var module1 = require("../src/module1.js");

describe("module1", function () {
    'use strict';

    it("should identify itself with whoAmI", function () {
        var me;
        me = module1.whoAmI();
        expect(me).toBe("module1");
    });

    it("should make a real AJAX request and return the title", function () {
        var callback = jasmine.createSpy("spy");

        module1.extractTitleFromBody(callback);

        waitsFor(function() {
            return callback.callCount > 0;
        }, "The request timed out.", 5000);

        runs(function() {
            expect(callback).toHaveBeenCalled();
        });

        runs(function() {
            expect( module1.getTitle()).toBe("Title Goes Here");
        });
    });
});