2016-05-21 3 views
1

Я видел это сообщение: https://www.codementor.io/nodejs/tutorial/manage-async-nodejs-callback-example-code, и после запуска кодов я подтверждаю, что nodejs является асинхронным. Однако я создал 2 файла js для повторной проверки функции асинхронности nodejs.Действительно ли Nodejs асинхронный?

Файл 1: callback_example.js

exports.countless = function(callback){ 
    var date = new Date(); 
    console.log("*" + date.getSeconds()); 
    var x = 0; 
    for(var i = 1; i <= 1000000000; i++){ 
     x++; 
    } 
    callback(x); 
    date = new Date(); 
    console.log("**" + date.getSeconds()); 
} 

exports.check = function(callback){ 
    var date = new Date(); 
    console.log(date.getSeconds()); 
    callback(123); 
    date = new Date(); 
    console.log(date.getSeconds()); 
} 

Файл 2: call.js

var call = require('./callback_example'); 

call.countless(function(x){ 
    console.log(x); 
}); 

call.check(function(x){ 
    console.log(x); 
}); 

И когда я исполню call.js в терминале, как node call, я увидел, что после бесчисленного количества(), затем проверьте() запустите. Это означает, что nodejs является синхронным? Почему? Может ли кто-нибудь помочь мне ответить на это? Большое спасибо!

+0

Слишком широкое представление о том, что * «nodejs является асинхронным» *, но он, безусловно, может использовать асинхронные операции. – charlietfl

ответ

2

node.js использует движок Javascript V8 и выполняет строки Javascript синхронно один за другим. Если вы пишете последовательные инструкции кодирования, например, в ваших методах countless и check в своем вопросе, то они выполняются синхронно, как и в любом другом языке программирования.

Вот часть описания node.js от https://nodejs.org/en/.

Node.js использует управляемую событиями, неблокирующую модель ввода-вывода, которая делает его легким и эффективным.

Это, я думаю, описывает это лучше, чем просто сказать, что node.js асинхронен, поскольку он лучше описывает то, что он на самом деле делает.

Только реальные асинхронные операции, которые используют какой-либо внешний интерфейс, например, сеть, фактически не блокируются в node.js. В этом случае вызов неблокирующей функции запускает операцию, а затем выполнение Javascript продолжается на следующих строках Javascript. Когда неблокирующая операция завершается в будущем, событие будет вставлено в очередь событий, и когда двигатель V8 завершит выполнение текущего потока выполнения, это событие можно вытащить из очереди событий, и вызов будет вызван ,

Вы не можете писать по-настоящему асинхронные операции с нуля (где фактический код выполняется в фоновом режиме) в чистом Javascript. Вам нужна помощь от внешнего интерфейса (например, сети, ввода-вывода файлов и т. Д.), Чтобы создать реальную операцию async. Вы можете имитировать один с таймерами, но на самом деле это не асинхронно, потому что ничего не выполняется в фоновом режиме. Таймеры просто меняют время, когда все происходит (они фактически не работают параллельно с выполнением Javascript).

Вот пример асинхронной операции в node.js:

var fs = require('fs'); 

console.log("one"); 
fs.readFile('temp.txt', function(err, data) { 
    if (err) { 
     console.log(err); 
    } else { 
     console.log("got data"); 
    } 
}); 
console.log("two"); 

Это создаст следующий вывод:

one 
two 
got data 

Операция fs.readFile() фактически асинхронная. После того, как вы его назовете, он выполняет свою работу в фоновом режиме, в то время как остальная часть вашего Javascript в последующих инструкциях продолжает выполняться. Когда он завершится, когда-нибудь в будущем, он будет называть его обратным вызовом либо с ошибкой, либо с данными.

+1

Я думаю, что ваша заметка о вещах, которые не являются «истинно» асинхронными, сбивает с толку. Для всех целей и задач обещания и 'setTimeout' определенно асинхронны, поскольку они завершаются« в какой-то момент в будущем ». –

+1

@DanPantry - Но они ничего не выполняют в фоновом режиме, поэтому все, что они 'setTimeout()' делает, это сдвиг времени кода. Я поставил это в своем ответе, чтобы попытаться отметить эту важную и значимую разницу. 'fs.readFile()' выполняет асинхронную работу в фоновом режиме. 'setTimeout (fn, 1000)' не выполняет никакой реальной работы в фоновом режиме - он просто сдвигает время, когда вызывается функция. – jfriend00

+0

@toilanvd - Это ответ на ваш вопрос? Если это так, нажмите зеленую галочку слева от ответа, чтобы сообщить об этом сообществу и заработать себе очки репутации для выполнения надлежащей процедуры здесь при переполнении стека. – jfriend00

1

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

Ваш пример здесь не использует асинхронный код вообще. Просто потому, что что-то внутри обратного вызова не обязательно означает, что оно асинхронно (иначе map будет асинхронным, например). Здесь вы просто используете функции более высокого порядка.

Попробуйте поместить их как внутри отдельных setTimeout s; заказ на вызов не будет гарантирован.

Node гарантирует работать до завершения (то есть, любая функция будет полностью выполнена, если она throws до первого return заявления), так что любой синхронный код будет выполняться в том порядке, как написано - так же, как и любой другой императив язык. Тем не менее, любые операции ввода-вывода или такие вещи, как использование Promise, будут добавлены в очередь задач, которые будут выполняться в какой-то момент в будущем, поэтому их порядок выполнения не гарантируется.

Обратите внимание, что NodeJS является однопоточным, а большие циклы for съедят этот единственный поток, так как это операция с привязкой к процессору, поэтому будьте осторожны, когда делаете компьютерные тяжелые вещи так, как вы повесите все свое приложение. Для сложного вычислительного материала вы можете уступить использованию детского процесса, написанного на другом языке, более подходящем для такой вещи (с использованием модуля child_process).

3

при вызове call.countless() выполняет эту функцию, однако внутри нее ничего не блокируется. Таким образом, Runtime занят выполнением операции цикла. Если бы вы написали любую операцию блокировки ввода-вывода, вы бы увидели асинхронный характер NODE JS.

например, блокировки ввода/вывод Операция: файл Чтение/запись, TimeOut, БД Операция, Ajax вызов

После того, как цикл завершен, то интерпретатор переходит на вторую функцию.

+0

Я думаю, вы имеете в виду неблокирующий ввод-вывод. Блокирование ввода-вывода будет очень плохо для узла. –

+0

Вот где красота лежит. Поскольку вышеперечисленные блокируют ввод-вывод, V8 Engine поместит это в цикл событий, поэтому один Node-поток будет свободен от этих блокирующих операций ввода-вывода, и он продолжит выполнение другой операции @DanPantry –

+0

Uh ... нет, он вообще не блокирует ввод-вывод. Блокирование ввода-вывода по определению - это когда текущий активный поток будет остановлен до завершения операции ввода-вывода. Узел не делает это по умолчанию (но имеет возможность сделать это с помощью операций module.xxxxSync).Все функции стандартной библиотеки Node I/O не блокируются, если вы не используете эти варианты. V8 не такой волшебный, как вы утверждаете. –

Смежные вопросы