Подтвердить что ты не робот

Определить, является ли метод синхронным или асинхронным

В node.js можно ли определить (используя функцию), является ли метод синхронным или асинхронным?

Я хотел бы написать функцию, которая делает следующее:

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

Ответ 1

С точки зрения языка это невозможно, и я считаю, что ответ lambda подтверждается.

  • Функции могут делать асинхронно, но возвращать что-то синхронно; скажем, вернуть количество асинхронных задач, которые были уволены.
  • Функции могут синхронно возвращать promises..., которые представляют асинхронную информацию. Я бы назвал такой метод асинхронным, но язык не может это сказать.
  • В некотором извращенном смысле каждая асинхронная функция "возвращает" что-то... undefined, если ничего другого.

С технической точки зрения:

  • прочитайте документацию.
  • Если функция принимает обратный вызов, она скорее асинхронна. Посмотрите на подпись функции.
  • Прочитайте код.
  • Используйте "здравый смысл". Если функция выполняет IO и возвращает результат из IO, она должна быть, в некоторых случаях, асинхронной. Это включает чтение файлов, чтение со стандартного ввода, сохранение в базу данных и запросы HTTP/AJAX. Для этого часто используются потоки сообщений, которые представляют собой асинхронную задачу, но обратные вызовы являются особыми.

Кроме того, есть функции, которые смешивают два.

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

Возможно, это очень плохо, и правильная практика будет

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

поэтому функция имеет равномерное поведение.

Однако есть хакерский способ сказать, произошло ли что-либо асинхронное, по крайней мере, в Node.js. См. эту дискуссию.

// 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.");
}

Это работает, потому что асинхронная работа не может разрешить по одному тику, по определению, и потому что Node.js однопоточная.

Ответ 2

Вы не обязательно знаете. Функция может быть даже случайной синхронной или асинхронной.

Например, функция, которая принимает другую функцию, может немедленно выполнить эту функцию или запланировать ее выполнение позднее, используя 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 все еще имеет синхронное возвращаемое значение (будь то undefined, обещание, thunk или что-то другое).

Ответ 3

Нет, это невозможно. Методы не только отмечены как синхронные или асинхронные, они либо используют обратные вызовы, либо не делают.