繁体   English   中英

Node.js异步函数*定义*

[英]Node.js Asynchronous Function *Definition*

请,只是为了清除我头脑中的一些东西......

我习惯在库中使用异步函数编写,但我如何编写自己的函数呢?

为了说明我的问题,我编写了一个名为'MadMathz'的模块

我知道以下是异步函数的示例用法:

//load module
var mM = require('./MadMathz');

//perform a function
mM.async_function_addthree(12, function(result) {
  console.log(result)
});

//do something straight afterwards
console.log('Logging this straight after instead of waiting for computation');

我知道函数的第二个参数是回调,但是如何定义'async_function_addthree'这样的函数? 让我们说这个例子的目的是async_function_addthree只是在第一个参数上加3。

我只是迷惑自己,试图写出我认为可能的东西。 我完全走错了路吗? 我觉得我接近使用node.js,但这需要清理。

如果可能的话,请解释而不是将我链接到某处。 我相信其他人会受益于这个问题。

实际上,在没有任何进一步描述或要求的情况下创建“ 异步 ”功能听起来有点奇怪。 通常,用法是避免长时间阻塞 因此,如果我们有一个触发数据库查询的函数,并且我们想在完成时调用另一个函数,那么在作业完成应该调用该函数,并且原始函数会立即将控制流返回给节点 (ECMAscript) 。

所以,如果我们有一个类似的结构

function someJob( callback ) {
    // heavy work
    callback();
}

现在,这段代码仍然非常同步 为了使它处于异步状态,我们可以调用node的process.nextTick方法

function someJob( callback ) {
    // heavy work
    process.nextTick( callback );
}

现在发生的是,Node将在稍后的运行中通过其eventloop执行该回调方法(并且它也有点聪明)。 Eventho nextTick声称比setTimeout更有效率,它几乎是相同的交易(来自ECMAscript编码器的观点)。 所以在浏览器中我们可以像

function someJob( callback ) {
    // heavy work
    setTimeout( callback, 0 );
}

如果说上面的示例方法根本没有多大意义,那么你会是正确的,因为异步状态发生繁重的工作之后。 嗯,是的。 事实上,你需要将沉重的部分分解成更小的和平,并使用.nextTick()来使用相同的想法,以使其真正有效。

这也是我在开始时混淆的原因,实际上每个任务都已经为你提供了回调的可能性。

这不是node.js模块代码,但我希望你明白这个想法。

函数是JavaScript中的第一类对象。 这就是为什么你可以将它们分配给变量并将它们传递给其他函数,如任何值。 一旦你有一个函数的引用,你只需通过在函数引用后put ()来调用它。

例:

function async_function_addthree(a, callback) {
    callback(a + 3);
}

这会向第一个参数添加3 ,然后调用第二个参数将结果传递给它。 请记住,您可以根据需要为参数命名。 重要的是第二个参数将包含一个可以调用的函数。

但请注意:接受回调的函数不会自动异步。 在此示例中,代码仍按其定义的顺序执行,即首先是async_function_addthree ,然后是回调,然后是调用async_function_addthree之后的所有内容,例如console.log

你可以添加一个setTimeout并调用延迟的回调:

function async_function_addthree(a, callback) {
    setTimeout(function() {
        callback(a + 3);
    }, 1000);
}

这会在一秒钟后调用回调。 Node.js甚至有更好的内置方式,请参阅jAndy的回答

但即使您的代码不是异步的,使用回调也是一个明智的设计选择,因为它允许您轻松地更改函数的行为,并在以后使其异步,而不会破坏现有代码。

当您将某些工作委托给外部流程(或者可能是Node的C层中的某些工作)时,会发生NodeJS流程中的异步性,例如数据库查询,文件系统操作。

通常在普通的JavaScript函数中没有异步性(Node.js是单线程的),没有太多有效的案例。 但是,如果它真的很重,并且你真的想这样做,你可以将你的工作委托给其他进程(参见child_process.fork)或借助setTimeout分割操作(让进程呼吸以处理其他请求),然后实际上它应该配置为异步功能。

我在寻找答案时遇到了这个问题。

基本上,要在节点中编写异步函数,您给它的一个参数应该是一个函数; 您将在以后的异步函数中调用该函数。

然后,当人们调用你的函数时,他们将能够定义该函数。

这是我以同步方式编写的代码示例,该代码不起作用,以及我如何将其重写为异步并实际工作。


以下代码不起作用:

//synchronous function that doesn't work
var google_request  = function(animal_name, sessionid){
    var options = {
        url: 'http://google.com',
        method: 'POST',
        json: {
            "animal": animal_name,
            "sessionid": sessionid
        }
    };

    request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            return body;
        }
    });
};

//use your function
var body = google_request("ant", "session1")
console.log(body); //this will return undefined

以下代码可以工作:

//asynchronous function
var google_request  = function(animal_name, sessionid, callback_function){
    var options = {
        url: 'http://google.com',
        method: 'POST',
        json: {
            "animal": animal_name,
            "sessionid": sessionid
        }
    };

    request(options, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            callback_function(body);
        }
    });
};

//use your function
google_request("ant", "session1", function(body){
    console.log(body); 
)};

这可能不是最简单的例子,但我对这个函数所做的更改非常简单; 我传递了我的函数第三个参数,称为“callback_function”,而不是返回“body”,我在body上调用了callback_function。 然后在下面我以通常的“节点”方式使用我的函数,而不是同步方式。

您可能还会发现此主题信息: 如何从异步调用返回响应?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM