Упомянутые вами концепции (управляемые событиями, неблокирующие, асинхронные, обратные вызовы) не являются специфическими для JavaScript, и понимание их в более общем контексте является ценным. Все они вращаются вокруг изящной обработки ресурсов, которые мы не можем контролировать.
Представьте, что вы ожидаете данных из TCP-соединения, ожидаете, пока ОС удалит файл, или ждете, когда пользователь нажмет кнопку. Если вы запрограммировали это поэтапно (шаг за шагом - синхронный ), вы пошли бы по кругу - «сделать шаг 1», «сделать шаг 2», «сделать шаг 3». «- пока не дойдете до шага« жди, что-нибудь случится ». В этот момент ваша программа остановится и откажется от бюджета, пока не получит данные, не получит подтверждение удаления или не нажмет кнопку. Другими словами, вызов блокирует выполнение программы. Это довольно неэффективно, учитывая, что, вероятно, существуют другие TCP-соединения, файловые операции и действия пользовательского интерфейса, которые требуют нашего внимания и не зависят от элемента, который мы ждем.
Во многих случаях было бы лучше указать, что мы заинтересованы в ресурсе, и получать уведомления вне пошаговых инструкций при изменении ресурса. Из вашего списка понятий:
- События - это изменения в ресурсах, которые нас интересуют - наше TCP-соединение получило некоторые данные, удаление файла завершено, или пользователь нажал кнопку.
- Асинхронные вызовы сообщают ОС или среде выполнения, что мы заинтересованы в том, чтобы что-то делать с ресурсом. Они неблокирующие - наша программа может работать на чем-то другом, пока она ожидает изменения ресурса.
- Обратные вызовы - это функции, которые должны выполняться при изменении ресурса. Асинхронный вызов ресурса часто принимает одну или несколько ссылок на функции обратного вызова (одна для успеха, одна для ошибки и т. Д.). Когда ресурс изменяется, среда выполнения вызывает соответствующий обратный вызов.
Эти концепции можно увидеть, переименовав файл с помощью node.js:
var fs = require('fs');
// args (current file name, new file name, callback function)
fs.rename('/tmp/hello', '/tmp/world', function (err) {
// this occurs when the rename is complete
if (err) throw err;
console.log('rename complete');
});
console.log('step after rename');
Третий аргумент может выглядеть странно. Это безымянная ( анонимная ) функция, которая будет вызываться после завершения переименования.
Обратите внимание, что поскольку fs.rename асинхронный, невозможно сказать, увидим ли мы сначала сообщение «переименовать завершено» или «шаг после переименования». В этом недостаток асинхронного программирования, управляемого событиями - если у нас сложный набор взаимозависимых задач, мы должны быть предельно осторожны, чтобы обеспечить завершение зависимых задач до выполнения задач, которые зависят от них. Тот факт, что порядок завершения асинхронного вызова может измениться, может привести к очень тонким ошибкам.
Смотри также:
Редактировать по запросу Дональда:
Лучший способ понять node.js - это загрузить, собрать, установить и использовать его. Вам понадобится:
- Mac OS или Linux. Если вам удобно с Cygwin, это также может быть вариантом, но если вы работаете в Windows, мне будет проще запускать Linux на виртуальной машине.
- Git - не требуется, но облегчает выборку хранилища кода.
- Способ отладки вашего приложения. См. этот вопрос . Первоначально запись отладочной информации в консоль может работать. В конце концов вам понадобится надежная отладка.
- Идея - что вы хотите делать с node.js? Если вам интересен обзор его возможностей, просмотрите его API .
Большинство учебных пособий посвящено способности node.js быстро создавать Http-сервер:
Имейте в виду, что node.js занимает очень специфическую нишу - он предназначен для создания сетевых программ.Возможно, это не тот инструмент, который подходит для других типов программ.