Как определить порядок выполнения для Node.js?

user3326078 спросил: 13 июня 2018 в 11:14 в: javascript

В настоящее время я пытаюсь проверить некоторый код Node.js. Теперь я пытаюсь выяснить, почему мой код console.log () в другом порядке относительно порядка выполнения кода. Это касается вызовов функций Node.js, связанных с ОС.

Мой скрипт делает это по порядку:

//First
fs.readdir(){ //read from a directory all the available files
   console.log some stuff #a
}//Second
fs.readFile(){ //read entire text file
   console.log some stuff #b
}//Third
//create readline interface using fs.createReadStream(filedir) theninterface{ //read from text file line by line
   console.log some stuff #c
}

Функция a использует путь: __dirname + '/ text_file / '
Функция b и c использует путь: __dirname,' /text_file/text1.txt'

Output:

a
c
b

Может кто-нибудь объяснить, почему этот порядок происходит? Я не эксперт в операционной системе или что происходит в фоновом режиме с помощью Node.js. Будет ли этот заказ испортить мое приложение, если я полагаюсь на это?

4 ответа

Есть решение
jfriend00 ответил: 13 июня 2018 в 11:47

Если вы запускаете несколько асинхронных операций, таких как одно за другим, порядок завершения является неопределенным. Эти операции выполняются независимо от вашего Javascript. Они называются "неблокирующими", что означает, что они немедленно возвращаются из вызова функции и ваш Javascript продолжает выполняться. Некоторое время спустя они заканчивают, вставляют событие в очередь событий Javascript, а затем вызывается обратный вызов, который вы передали ему. Асинхронный, неблокирующий аспект этих функций означает, что они не "ждут" завершения операции перед возвратом.

Порядок завершения нескольких асинхронных операций, которые все находятся в полете по то же время будет просто зависеть от того, какой из них завершит свою работу перед другими.

Если вы хотите, чтобы они выполнялись последовательно, тогда вам нужно специально закодировать их для запуска последовательно, запустив вторую операцию в завершении обратный вызов первого и запуск третьего в обратном вызове завершения третьего.

Например:

fs.readdir(somePath, function(err, files) {
    if (err) {
        console.log(err);
    } else {
        fs.readFile(someFilename, function(err, data) {
            if (err) {
                console.log(err);
            } else {
                // done with both asynchronous operations here
                console.log(data);
            }
        });
    }
});

Некоторые другие релевантные ссылки по теме:

Как разрешить асинхронный метод readFile следовать порядку в node.js

Как синхронизировать последовательность обещаний?

Как установить конкретный порядок выполнения при асинхронных вызовах?

Как выполняется асинхронное выполнение Javascript? и когда не использовать оператор return?

синхронная и асинхронная путаница с одним потоком

Почему функции callbacks позволяют нам делать асинхронно в Javascript?

jfriend00 ответил: 13 июня 2018 в 11:49
@ user3326078 - Добавлен ряд других полезных ссылок.
user3326078 ответил: 15 июня 2018 в 06:28
Да. Спасибо. Не знаете, как выбрать ответ на темы вопроса SO ... Редактировать: NVM.
Kroltan ответил: 13 июня 2018 в 11:29

readdir и readFile являются асинхронными, то есть они обрабатывают вне основного потока кода. Вот почему вы можете дать им обратный вызов, который выполняется после завершения операции, что может занять много времени (в понятии времени компьютера).

Вы не можете полагаются на выполнение асинхронных функций до выполнения следующей синхронной строки кода. Это означает, что в конечном итоге ваш код будет выглядеть следующим образом:

fs.readdir(someDir, function(err, files) {
    if (err) return;
    // do stuff with the list of files in the directory    fs.readFile(someFile, function(err, contents) {
        if (err) return;
        // do stuff with the file's contents
    });
});

Почему асинхронный, вы можете спросить? Ну, может быть, вы можете заниматься другими вещами, пока (очень медленный) диск вращается вокруг, пытаясь найти ваши данные. Остановка всей программы во время чтения диска будет очень заметной тратой времени, поэтому Node выполняет такие операции, которые зависят от дискового или сетевого асинхронного режима, что освобождает вас от продолжения любой другой обработки до тех пор, пока они не будут выполнены.

Конечно, это означает, что вам нужно написать код, который зависит от вывода таких асинхронных операций внутри обратного вызова.


В другом примечании:

Надеюсь, вы увидите, что для больших приложений этот стиль кодирования очень громоздкий, так как основной код всегда будет идти вправо, а отслеживание ошибок сложно. Вот почему Promise s были изобретены, и я бы рекомендовал вам их изучить, но после вы понимаете нормальную асинхронность.

Kroltan ответил: 13 июня 2018 в 11:30
Я отредактировал ответ с немного дополнительной информацией.
user3326078 ответил: 15 июня 2018 в 06:30
Мне очень нравятся как вы, так и ответ jfriend00, я мог бы выбрать оба :(
Kroltan ответил: 15 июня 2018 в 06:33
@ user3326078 у него есть ссылки ссылки, это более полезно в долгосрочной перспективе для других посетителей этого сайта.
Chico3001 ответил: 13 июня 2018 в 11:45

В отличие от традиционных языков программирования, JavaScript (и его варианты, такие как NodeJS) запускают код параллельно, каждая асинхронная функция запускается независимо от других, и из-за этого программа не запускается последовательно, это делает выполнение быстрее, но сложнее control

для обработки синхронных функций есть библиотеки, такие как ASYNC, которые позволят вам контролировать, что делать, когда одна или несколько функций заканчиваются, и поможет вам ограничить или устранить обратный ад.

https://www.sohamkamani.com/blog/2016/03/14/wrapping-your-head-around-async-programming/

Kroltan ответил: 13 июня 2018 в 11:31
Нет, JavaScript not работает параллельно. Он работает с анимически , что существенно отличается. JavaScript, в частности, однопоточный. Никакие две строки JavaScript никогда не будут выполняться одновременно.
Chico3001 ответил: 13 июня 2018 в 11:44
Вы правы, никакие две строки javascript не будут выполняться одновременно, но когда мы сделали два асинхронных вызова и продолжаем продвигаться в выполнении нашего кода, три функции работают одновременно (наша программа и ОС, заканчивая 2 асинхронные функции), это то, что я хотел объяснить
Kroltan ответил: 13 июня 2018 в 11:45
Достаточно справедливо, я просто задирал, потому что терминология уже не очевидна, когда она не используется неправильно.
Guzz ответил: 13 июня 2018 в 11:44

Все эти функции являются асинхронными и будут выполняться параллельно. fs.readFile будет выполняться обратный вызов после того, как будет прочитан весь файл, как для fs.createReadStream callback будет выполняться, когда первый фрагмент потока будет читаемым, и это будет быстрее первого.

Dave Newton ответил: 13 июня 2018 в 11:51
Это более или менее то, о чем говорили более ранние ответы, нет? (И с более подробной информацией.) Они не выполняются параллельно, хотя, как указывал предыдущий правильный nitpick.
Guzz ответил: 15 июня 2018 в 04:47
Я просто хотел указать, что объект потока ведет себя по-разному, и он должен выполнить обратный вызов раньше. И да, они запускают выполнение каждой функции по порядку, но createReadStream не дожидается, пока функция readFile не завершится, неправильно сказать, что она параллельна, но в некотором роде, в то время как первая функция все еще выполняет вторую, уже запущенную ,

Дополнительное видео по вопросу: Как определить порядок выполнения для Node.js?

Learn nodejs, Asynchronous mocha testing

JavaScript - Асинхронные функции (async/await)

Async/Await - Node.js Basics Part 6