[英]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.