Хорошо, давайте посмотрим на это по частям.Просто помните, что Node.js - это однопоточный процесс, и если ему нужно выполнить blocking processes
, например, чтение файла (создать указатель события, прочитать дескриптор файла, задать путь к файлу,установить открытый режим и т. д.) лучше использовать асинхронные функции, которые выполняются в отдельном потоке одной и той же страницы или в потоке / пуле.
1) Асинхронные функции хорошо использовать, когданезависимая операция (из основного потока программы) для выполнения.Не идеально использовать асинхронные функции, когда основная программа требует данных / ответа от асинхронной функции или когда различные независимые асинхронные функции взаимосвязаны.
Для начала мы не будемименуйте файл программы как main program
, так как в мире Node.js нет подпрограмм (я не говорю о модулях и тому подобное).
Теперь вы действительно правы, когда говорите, что не должны использовать никакие асинхронные функции, когда есть непосредственная необходимость в выводе.Давайте возьмем следующий пример:
...
const data = readFile( 'fileName', ( data, output ) => {
...
} );
console.log( data ); // this might be null or undefined
В вышеприведенном случае мы не будем использовать асинхронную функцию (в традиционном смысле).Однако, с ES6 и выше, мы получаем прекрасную парадигму async/await
:
const data = await readFile( 'filename' );
await
делает псевдосинхронизацию вызова: она ведет себя как функция async
,но будет приостановленный поток, чтобы ждать вывода.Итак, здесь вы абсолютно правы!Давайте двигаться дальше.
2) Нехорошо зависеть от результата вывода асинхронной функции в основной поток программы.Потому что Async всегда выполняется после основного потока.Поэтому, если вам нужно, чтобы некоторые функции выполнялись в основном потоке, лучше определить его как Синхронный, а не асинхронный.
Здесь вы говорите, что async
работает после основного потока.Теперь , что неверно.Позвольте мне нарисовать простую картину оценки и выполнения потока:
Скажем, есть две sync
функции A()
и B()
, и их соответствующие потоки th__A
и th__B
, они будутпойти примерно так:
th__a ---> th__b
Если они стреляют в порядке A()
, то B()
Он ожидает оценки первого процесса синхронизации (или блокировки), а затем выполняет второй.Как видно, это НЕ после того, как закончится все выполнение.
Однако, если они теперь являются асинхронными функциями, они будут выполняться параллельно.Скажем, A()
был функцией синхронизации, а B()
был асинхронной функцией с теми же именами потоков, что и выше, выполнение выглядит примерно так:
th__a ----
- - th__b ->
Где -
представляет тактовый цикл, а ->
представляет конец выполнения.Мы видим, что A()
запускается, а затем в новом потоке B()
запускается.
Я думаю, это имеет смысл.Теперь, возвращаясь, снова, если вам нужно использовать их немедленно, а затем в качестве асинхронных вызовов, используйте await
.
3) Когда вызываются независимые асинхронные функции, обычной практикой является вызов последующей операции (асинхронной функции) с использованием обещаний или обратных вызовов.
Абсолютно.
Скажем, мы определяем функцию sayHello()
:
const sayHello = () => {
const P = Q.defer();
// P.resolve(data);
// or if there is an exception
// P.reject(error);
return p.promise;
};
, где Q
- отличная библиотека обещаний.Мы можем назвать это как:
sayHello.then( ( data ) => {
console.log( data ); // P.resolve(..) is working here since the promise was successful.
} ).catch( ( err ) => {
console.log( err ); // P.reject(..) is working here since there was a problem.
} );
Или вы можете использовать обратные вызовы, такие как fs.readFile(...)
:
fs.readFile( 'fileName', ( e, data ) => {
if( e ) { return console.log( e ); } // error was handled
// perform subsequent functions here with data
} );
4) Iвсе еще может вызывать функцию синхронизации внутри функции Async, но программа может работать не так, как ожидалось, если функция / функция Async вызывается из функции / операции синхронизации, поскольку функция асинхронности будет выполняться только в последний раз?
Не совсем.Обратитесь к пункту (2).Это о нитях.Нестатические процессы.Вы можете очень хорошо вызвать функцию синхронизации внутри асинхронной функции, и она будет отлично работать.
Когда вы читаете файл, скажем, что вы хотите разделить данные на \n
или новую строку:
...
if( e ) { return console.log( e ); }
const dataLines = e.split( '\n' ); // this will work brilliantly
...
Надеюсь, это прояснило все!:)