如何识别回调是同步执行还是异步执行? [复制]

Posted

技术标签:

【中文标题】如何识别回调是同步执行还是异步执行? [复制]【英文标题】:How to identify if a callback is going to be executed synchronously or asynchronously? [duplicate] 【发布时间】:2014-11-21 07:01:27 【问题描述】:

我正在学习 node.js。到目前为止,我已经理解了回调的含义,但我不确定回调是同步执行(调用者在回调返回之前不会继续执行)还是异步执行(调用者进行回调并继续执行其代码)。

【问题讨论】:

好问题,欢迎来到 SO :) 我是在 node.js 的上下文中问的 【参考方案1】:

您无法通过查看函数调用来判断。 Some callbacks are asynchronous, others are not。您需要查看文档,它应该在那里说明。

您通常可以通过函数的签名将它们区分开来。如果一个回调预计只在计算结果中被调用一次,并且回调和函数都不返回任何内容,则通常会异步调用回调(setTimeoutreadFile 等)。如果函数立即返回结果,通常会同步调用多次回调(Array::sortArray::map)并产生有价值的值。当然,例外证明了规则,有时您无法轻易分辨,例如setIntervalArray::forEach(均不返回任何内容,并多次调用回调)。

【讨论】:

【参考方案2】:

我会尝试重新表述您的问题,因为“异步函数调用”和“异步 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:不要试图依赖这个顺序,除了带有回调参数的众所周知的标准函数(数组的 forEach、map 等、字符串替换器、JSON reviver)

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

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”的顺序,构建你的代码不依赖于“async or not foo is”

【讨论】:

【参考方案3】:

您可以为此使用标志:

var async = false;

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

async = true;

【讨论】:

我不想使用标志。

以上是关于如何识别回调是同步执行还是异步执行? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

nodejs是同步还是异步

node.js中的forEach是同步还是异步

js定时器 settimeout和其他代码是同步执行还是异步执行

Javascript 默认是同步(阻塞)还是异步(非阻塞)

同步与异步,阻塞与非阻塞

js函数可以同步执行么