nodejs使用module.exports进行回调

时间:2016-04-16 08:49:45

标签: node.js module callback

我从NodeJS开始,并试图了解回调如何与module.exports相关。

我有两个NodeJS文件。

  1. s1.js接收输入字段msg并将结果传回。 s1.js是 通过module.exports公开。
  2. start.js包含s1.js(通过require)并收到我想在程序中使用的结果
  3. start.js

    var s1=require('./s1.js');
    var r1;
    s1.test("Leon", function(err, result) {
        if (err){console.log("Error occurred "+err);}
        console.log("Callback after s1.test execution "+result);    
        r1=result;
    }   
    );
    console.log("result "+r1);
    console.log("end");
    

    s1.js

    module.exports.test=function test(msg,result){
        result="Hello "+msg;
        console.log("Inside s1.js - "+result);
    };
    

    当我执行start.js时,结果在

    之下
    Inside s1.js - Hello Leon
    result undefined
    end
    

    正如预期的那样,结果是未定义的,因为s1.test的回调尚未完成。
    我不明白为什么从来没有达到s1.test的回调。

    有什么想法吗?
    感谢 列昂

3 个答案:

答案 0 :(得分:4)

之前的答案是正确的,但你的问题与nodejs或module.exports没什么关系,但问题是你还没有理解JavaScript(以及PHP和其他语言)中使用的回调的本质。 / p>

您使用的示例实际上使这种差异更难理解。所以这里是一个关于如何理解回调的循序渐进的描述,从简单的语句开始,到代码看起来像你的。

// Create some object
var fooBar = { foo: 'foo object'};

// Add a bar function to that object
fooBar.bar = function (param1, param2) {
    console.log("Inside bar function: " + param1);
};

运行此代码并不会创建任何内容,因为对象已创建并添加了一个函数,但该函数永远不会被调用。

为此,我们需要添加对该函数的调用:

fooBar.bar('test 1');

现在我们得到输出:

Inside bar function: test 1

或者我们可以调用该函数两次:

fooBar.bar('test 1');
fooBar.bar('test 2');

现在我们得到输出:

Inside bar function: test 1
Inside bar function: test 2

下一步是创建一个类似于s1.test()调用中用作第二个参数的函数。但是,不是将其分配给该参数,而是将其分配给另一个变量。

// Create some object
var fooBar = { foo: 'foo object'};

// Add a bar function to that object
fooBar.bar = function (param1, param2) {
    console.log("Inside bar function: " + param1);
};

// Create assign a function to a variable
var func = function (err, result) {
    console.log("Inside func function, call using: " + err + " and " + result);    
}   

fooBar.bar('test 1');
fooBar.bar('test 2');

她将函数分配给变量funcfunc只是另一个变量,其类型为function。 JavaScript中的回调只是一个类型为function的变量。要看到这个运行:

console.log(typeof func);

输出结果为:

function

输出没有改变! 将此新函数定义并作为回调分配给变量不会运行代码!您需要调用该函数来运行代码。所以我们开始调用函数并将最后两行更改为四行:

func('outside', 'call 1');
fooBar.bar('test 1');
fooBar.bar('test 2');
func('outside', 'call 2');

现在的输出是:

Inside func function, call using: outside and call 1
Inside bar function: test 1
Inside bar function: test 2
Inside func function, call using: outside and call 2

现在,为了更接近您的示例,我们将func变量作为第二个参数传递给fooBar.bar()函数:

func('outside', 'call 1');
fooBar.bar('test 1', func);
fooBar.bar('test 2', func);
func('outside', 'call 2');

输出仍然是:

Inside func function, call using: outside and call 1
Inside bar function: test 1
Inside bar function: test 2
Inside func function, call using: outside and call 2

为什么呢?因为fooBar.bar()函数内的代码对第二个参数没有任何作用。所以我们将此功能更改为:

// Add a bar function to that object
fooBar.bar = function (param1, param2) {
    console.log("Inside bar function: " + param1);
    console.log("The type of param 2 is: " + typeof param2);
};

结果输出类似于::

Inside func function, call using: outside and call 1
Inside bar function: test 1
The type of param 2 is: function
Inside bar function: test 2
The type of param 2 is: function
Inside func function, call using: outside and call 2

此输出显示param2的值是函数本身,而不是输出结果!要运行代码,我们需要做的就是使用param2作为函数,我们甚至可以多次调用该函数:

// Add a bar function to that object
fooBar.bar = function (param1, param2) {
    param2("inside bar 1", param1);
    console.log("Inside bar function: " + param1);
    param2("inside bar 2", param1);
};

结果是:

Inside func function, call using: outside and call 1
Inside func function, call using: inside bar 1 and test 1
Inside bar function: test 1
Inside func function, call using: inside bar 2 and test 1
Inside func function, call using: inside bar 1 and test 2
Inside bar function: test 2
Inside func function, call using: inside bar 2 and test 2
Inside func function, call using: outside and call 2

现在终于可以创建看起来像start.js的代码了。我们不使用函数创建变量func,而是使用匿名函数,例如您的示例。完整的代码变为:

// Create some object
var fooBar = { foo: 'foo object'};

// Add a bar function to that object
fooBar.bar = function (param1, param2) {
    param2("inside bar 1", param1);
    console.log("Inside bar function: " + param1);
    param2("inside bar 2", param1);
};

// fooBar.bar('test 2', func);

// Use anonymous function instead of func
fooBar.bar('test 3', function (err, result) {
    console.log("Inside anonymous function, call using: " + err + " and " + result);    
}
);

输出现在变为:

Inside anonymous function, call using: inside bar 1 and test 3
Inside bar function: test 3
Inside anonymous function, call using: inside bar 2 and test 3

我们可以使用其他功能向fooBar.bar添加另一个调用:

fooBar.bar('test 4', function (err, result) {
    console.log("Inside another anonymous function, call using: " + err + " and " + result);
}
);

输出:

Inside anonymous function, call using: inside bar 1 and test 3
Inside bar function: test 3
Inside anonymous function, call using: inside bar 2 and test 3
Inside another anonymous function, call using: inside bar 1 and test 4
Inside bar function: test 4
Inside another anonymous function, call using: inside bar 2 and test 4

我希望这些例子说明为什么你的start.js中的匿名函数永远不会被调用。

最后一个感兴趣的注意事项:创建匿名函数并将其分配给变量并在javaScript中创建函数之间是否存在差异?那是在:

之间
// Create assign a function to a variable
var func = function (err, result) {

    console.log("Inside func function, call using: " + err + " and " + result);    
}

function func (err, result) {
    console.log("Inside func function, call using: " + err + " and " + result);    
} 

答案是否定的!两者都在全局堆栈中创建名为func的指针以指向相同的函数。您甚至可以使用其他名称创建一个全局函数,并使func变量指向它。此示例与前一个示例一样有效:

function funcy (err, result) {
    console.log("Inside func function, call using: " + err + " and " + result);    
} 

var func = funcy;

换句话说:变量可以指向函数,就像变量可以指向字符串,整数或对象一样。功能是"只是"变量可以指向的类型之一。

将此函数分配给变量不会执行代码!为此,您必须调用变量指向的函数。

答案 1 :(得分:0)

您没有拨打回叫。回调只是普通函数,只是作为函数的参数给出。

您的代码不会调用回调。您正在尝试为回调设置值。固定版本的s1.js:

module.exports.test=function test(msg,result){
    result(null, "Hello "+msg);
    console.log("Inside s1.js - "+result);
};

这样你就可以调用回调。我们需要传递null,因为您已将回调函数定义为function(err, result)。它有两个参数,第一个是err我们没有遇到错误,所以我们只是传入null

答案 2 :(得分:0)

请尝试以下 s1.js 的示例,代码是自解释的,如果您仍需要帮助,请与我们联系。

var defaultValues = module.exports

defaultValues.GetApiURL = function () {
    var apiURL = "http://localhost:1000/api/"
    return apiURL;
}