确定方法是同步还是异步

时间:2012-10-01 20:06:22

标签: javascript node.js

在node.js中,是否可以确定(使用函数)方法是同步还是异步?

我想编写一个执行以下操作的函数:

function isSynchonous(methodName) {
    //if the method is synchronous, return true. Otherwise, return false.
}

3 个答案:

答案 0 :(得分:6)

从语言的角度来看,这是不可能的,我相信llambda的回答证明了这一点。

  • 函数可以异步执行,但同步返回某些内容;比如说,返回被触发的异步任务的数量。
  • 函数可以同步返回表示异步信息的promises。我会称这种方法是异步的,但语言无法说明这一点。
  • 在某种反常的意义上,每个异步函数都会返回"什么...... undefined如果没别的话。

从工程角度来看:

  • 阅读文档。
  • 如果函数接受回调,则可能是异步的。查看函数签名。
  • 阅读代码。
  • 使用"常识。"如果函数执行IO并从IO返回结果,则在某些情况下,它必须是异步的。这包括文件读取,从标准输入读取,保存到数据库以及HTTP / AJAX请求。注意流通常用于此,它表示异步任务,但回调是特殊的。

此外,函数混合了两者。

function(callback) {
    if(ready) {
        callback();
    }
    else {
        setTimeout(callback, 5000);
    }
}

可以说这是非常邪恶的,正确的做法是

if(ready) {
    process.nextTick(callback);
}

所以函数具有统一的行为。

然而 是一种hacky方式来判断是否发生了异步,至少在Node.js 中。请参阅this discussion

// untested!! please read the documentation on these functions before using yourself
var work = process._getActiveHandles().length + process._getActiveCallbacks().length;
foo;
var newWork = (process._getActiveHandles().length + process._getActiveCallbacks().length) - work;
if(newWork > 0) {
    console.log("asynchronous work took place.");
}

这是有效的,因为根据定义,异步工作不能在同一个tick上解析,因为Node.js是单线程的。

答案 1 :(得分:5)

你不一定知道。函数甚至可以是随机同步或异步的。

例如,一个带另一个函数的函数可以立即执行该函数,或者它可以安排在以后使用setImmediate或nextTick执行它。该函数甚至可以随机选择同步或异步调用其传递的函数,例如:

console.log('Start')

function maybeSynchOrAsync(fun) {

  var rand = Math.floor((Math.random() * 2))

  if (rand == 0) {
    console.log('Executing passed function synchronously')
    fun()
    console.log('Done.')
  } else {
    console.log('Executing passed function asynchronously via setImmediate')
    setImmediate(fun)
    console.log('Done.')
  }
}

maybeSynchOrAsync(function () { console.log('The passed function has executed.') });

此外,从技术上讲,每个函数调用都是同步的。如果您调用函数 F ,并且 F 将稍后调用的回调函数排队(使用setTimeout或任何机制),则原始函数 F 仍然有一个同步返回值(无论是未定义,承诺,thunk还是其他)。

答案 2 :(得分:3)

不,那是不可能的。这些方法不只是标记为同步或异步,它们要么使用回调,要么不使用回调。