所有节点都是“;回调”;潜在异步功能
Are All Node "callback" Functions Potentially Asynchronous?
我是一个(相对的)节点新手,社区里对"只写回调,一切都是异步和事件驱动的,别担心
如果我有以下程序在节点下运行
var foo = function(){
console.log("Called Foo");
};
var bar = function(){
console.log("Called Bar");
};
var doTheThing = function(arg1, callback){
callback();
};
doTheThing(true, function() {
foo();
});
bar();
在bar
之后,foo
是否有执行的机会?当我在本地通过命令行运行程序时,它总是
Called Foo
Called Bar
但我看到了很多来自善意的传道者的警告,比如不要认为你的回调会在你认为会被调用的时候被调用,我不清楚他们是在警告我库实现的细节,还是node.js在你使用函数对象作为参数时做了一些奇怪/特别的事情。
不,没有机会。不适用于该代码。
如果你正在编写自己的函数,或者你有权访问代码,你不需要假设,你知道一切是否同步,但如果你没有访问代码的权限,或者还没有阅读它,那么不,你不能假设回调将是同步的。
然而,做出这样的假设是一种糟糕的做法,原因有两个,第一,仅仅因为它现在是同步的并不意味着其他人,也不意味着你以后不能改变它,第二,因为如果它都是同步的,你/他们为什么一开始就使用回调?回调的全部目的是允许异步调用的可能性。使用回调,然后表现得好像它们总是同步的,即使你知道是这样,也会让你的代码让其他人感到困惑
否
您的示例代码是100%同步的、单线程的、从上到下简单的。但这是因为您不执行任何I/O,没有任何真正的异步调用,也不使用process.nextTick
、setTimeout
或setInterval
。要更真实地模拟异步调用,请执行以下操作:
function fakeAsync(name, callback) {
setTimeout(function () {
callback(null, name);
}, Math.random() * 5000);
}
function logIt(error, result) {
console.log(result);
}
fakeAsync('one', logIt);
fakeAsync('two', logIt);
fakeAsync('three', logIt);
运行几次,有时你会看到不正常的结果。
foo有可能在bar之后执行吗?
在当前代码中,没有。尽管doTheThing
函数有一个异步函数签名(即,它将回调作为最后一个参数,对于不了解函数实现的局外人来说,这意味着它是异步的),但它实际上是完全同步的,并且callback
将在不向运行时让步的情况下被调用。
但是
您真的没有理由给doTheThing
代码一个异步签名,,除非您愿意在某个时候将真正的异步行为引入doTheThing
。在这一点上,你有一个问题,因为foo
和bar
的调用顺序会翻转。
在我看来,只有两种像您这样编写代码的好方法:要么让doTheThing
是同步的(最重要的是:它不会依赖于I/O),这意味着您可以简单地从函数返回:
doTheThing = function(arg1){
return null
};
doTheThing()
foo()
bar()
或者直接改变doTheThing
的存根实现以包括对setImmediate
的调用,即
var doTheThing = function(arg1, callback){
setImmediate(function() { callback(); );
};
注意,这也可以写成
var doTheThing = function(arg1, callback){
setImmediate(callback);
};
但这只是因为此时回调不接受任何参数。第一个版本更接近您的版本。
一旦这样做,bar
将始终在foo
之前被调用,并且现在可以安全地将异步功能引入doTheThing
。
- 异步facebook功能
- 为什么同步睡眠功能没有被承诺内异步化
- 异步功能在预期结果时停止工作
- 间谍无法跟踪与摩卡和西农的异步功能测试
- 替换功能内的异步加载
- 异步功能完成后执行函数
- 是否有在“异步”中实现的非递归功能
- 异步功能取决于量角器测试中的外部模块
- 如何将节点 js 的异步功能处理为在节点 js 中同步
- ES7异步功能和promise之间的技术差异
- NodeJS.异步.平行的功能相同
- 所有节点都是“;回调”;潜在异步功能
- 流星铁路由器等待与异步功能
- 如何渲染异步数组的结果forEach '功能
- Nodejs异步数据库功能需要同步应答
- IF语句的控制流程&异步功能
- 使用promise链接同步与异步功能时的工作流
- Javascript的功能是同步的还是异步的
- 对angular服务的异步调用完成后调用控制器功能
- 具有异步功能的 for 循环会耗尽内存