Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/416.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 都是节点“;“回调”;函数可能是异步的?_Javascript_Node.js_Callback - Fatal编程技术网

Javascript 都是节点“;“回调”;函数可能是异步的?

Javascript 都是节点“;“回调”;函数可能是异步的?,javascript,node.js,callback,Javascript,Node.js,Callback,我是一个(相对而言)进入系统的节点新手,社区中对“只需编写回调,一切都是异步和事件驱动的,不用担心!”的热情让我对单个程序中的控制流感到有点困惑(或者更详细地说,在较大程序中处理单个请求期间的控制流) 如果在节点下运行以下程序 var foo = function(){ console.log("Called Foo"); }; var bar = function(){ console.log("Called Bar"); }; var doTheThing = funct

我是一个(相对而言)进入系统的节点新手,社区中对“只需编写回调,一切都是异步和事件驱动的,不用担心!”的热情让我对单个程序中的控制流感到有点困惑(或者更详细地说,在较大程序中处理单个请求期间的控制流)

如果在节点下运行以下程序

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();
是否有
foo
bar
之后执行的可能性?当我在本地通过命令行运行程序时,它总是

Called Foo
Called Bar
但是我看到很多善意的布道者的警告,比如不要假设你的回调会在你认为会被调用的时候被调用,我不清楚他们是在警告我库的实现细节,还是node.js在你使用函数对象作为参数时做了一些奇怪/特殊的事情。

否 您的示例代码是100%同步、单线程、简单的自上而下的。但这是因为您不做任何I/O、没有任何真正的异步调用,也不使用
进程。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);
运行几次,您有时会看到无序的结果。

否 您的示例代码是100%同步、单线程、简单的自上而下的。但这是因为您不做任何I/O、没有任何真正的异步调用,也不使用
进程。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有没有可能在酒吧后被处决

在您当前的代码中,不是。尽管您的
doTheThing
函数具有异步函数签名(即,它将回调作为最后一个参数,对于不了解函数实现的外部人员来说,这表明它是异步的),它实际上是完全同步的,
回调
将被调用,而不会屈服于运行时

然而

你真的没有理由给你的
doTheThing
代码一个异步签名,除非你愿意在某个时候把真正的异步行为引入
doTheThing
。在这一点上,你有一个问题,因为调用
foo
bar
的顺序会颠倒

在我看来,像您这样编写代码的好方法只有两种:要么将
设置为同步(最重要的是:它不会依赖于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

foo有没有可能在酒吧后被处决

在您当前的代码中,不是。尽管您的
doTheThing
函数具有异步函数签名(即,它将回调作为最后一个参数,对于不了解函数实现的外部人员来说,这表明它是异步的),它实际上是完全同步的,
回调
将被调用,而不会屈服于运行时

然而

你真的没有理由给你的
doTheThing
代码一个异步签名,除非你愿意在某个时候把真正的异步行为引入
doTheThing
。在这一点上,你有一个问题,因为调用
foo
bar
的顺序会颠倒

在我看来,只有tw