如何判断回调函数是同步执行还是异步执行?

4

我正在学习node.js。目前,我已经理解了回调函数的含义,但我不确定回调函数是同步执行(调用者在回调返回之前不会继续向前)还是异步执行(调用者在调用回调函数后继续向前执行自己的代码)。


1
好问题,欢迎来到 SO :) - DrakaSAN
我是在node.js的上下文中提出这个问题的。 - avinashkrsharma
3个回答

3

从函数调用中你无法真正判断。一些回调是异步的,而另一些则不是。你需要查看文档,在那里应该会有说明。

通常你可以通过函数的签名来区分它们。如果期望一个回调只被调用一次,并返回计算结果,而且既没有回调也没有函数返回任何内容,那么回调通常是异步调用的(setTimeoutreadFile等)。如果函数立即返回结果,则通常同步调用多次回调(Array::sortArray::map),并产生有价值的值。当然,例外证明规则,有时你无法轻易地判断,例如 setInterval vs Array::forEach(两者都不返回任何内容,并多次调用回调)。


1
我会尝试重新表述您的问题,因为“异步函数调用”和“异步IO”术语中存在很多混淆。
让我们这样写:在不查看“foo”源代码的情况下,给定以下代码,我们能否运行一些测试来确定输出是“Line 1\nLine2”还是“Line 2\nLine1”?
var t1 = asyncTestCapture();
foo(function() {
   console.log("Line 1");
});
console.log("Line 2");
var out12vsOut21 = asyncTestVerify(t1);

答案1:除了一些带有回调参数的众所周知的标准函数(例如Array的forEach、map等,String replacer和JSON reviver),不要试图依赖此顺序。

答案2:(请注意,我对代码进行了非常简要的测试,它是特定于node.js的,但我相信它可以回答“out12vsOut21”的问题。还请注意,我正在使用未经记录的node函数)

function asyncTestCapture() {
  return {
    activeHandles:  process._getActiveHandles(),
    activeRequests: process._getActiveRequests()
  };
}

function asyncTestVerify(handles1) {
  var handles2 = asyncTestCapture();
  return handles2.activeHandles === handles1.activeHandles && handles2.activeRequests === handles1.activeRequests
}

我再重复一遍:如果你需要上面的代码,那么你的设计有问题。你不需要知道"out12vsOut21"的顺序,构建你的代码,使其不依赖于"异步或非foo is"。

-1
你可以使用一个标志来实现这个功能:
var async = false;

someFunction(function () {
  console.log(async ? 'async' : 'sync');
});

async = true;

我不想使用标志。 - avinashkrsharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接