Предисловие
Самым большим событием NodeJS является модель неблокирующей вводы/вывода, основанная на событиях, которая заставляет NodeJS обладать сильными возможностями обработки параллелистики и очень подходит для написания сетевых приложений. Большинство операций ввода/вывода в Nodejs практически асинхронно, то есть результаты наших операций ввода -вывода в основном необходимо обработать в функции обратного вызова, например, следующая функция, которая считывает содержимое файла:
Кода -копия выглядит следующим образом:
fs.readfile ('/etc/passwd', function (err, data) {
if (err) бросить ошибку;
console.log (data);
});
Итак, что мы должны делать, если мы прочитаем два файла и объединили содержимое этих двух файлов вместе? Большинство людей, которые не соприкасаются с JS, могут сделать это:
Кода -копия выглядит следующим образом:
fs.readfile ('/etc/passwd', function (err, data) {
if (err) бросить ошибку;
fs.readfile ('/etc/passwd2', function (err, data2) {
if (err) бросить ошибку;
// обработать данные данных и данных здесь
});
});
Если вы имеете дело с несколькими аналогичными сценариями, разве не так ли, что функции обратного вызова вложенного слоя по слою? Это то, что люди часто называют пирамидой или обратным адом (http://callbackhell.com/), и это также самая проблематичная проблема для новичка JS.
Этот вид вложенного кода вызвал много проблем в разработку, в основном отражено в:
1. Возможность кода становится хуже
2. отладки трудностей
3. Трудно проверить после того, как произошло исключение
В этой статье в основном представлены, как решить вышеупомянутые асинхронные проблемы обратного вызова элегантно.
Первичное решение: рекурсивно обрабатывать асинхронные обратные вызовы
Мы можем использовать рекурсию в качестве инструмента управления выполнением для кода. Инкапсулируйте операции, которые необходимо выполнить в функцию, и управлять процессом выполнения кода путем повторного вызова в функции обратного вызова. Без лишних слов, давайте поговорим о глупости, давайте посмотрим на предыдущий код:
Кода -копия выглядит следующим образом:
var fs = require ('fs');
// Список файлов, которые должны быть обработаны
var files = ['file1', 'file2', 'file3'];
function parsefile () {
if (files.length == 0) {
возвращаться;
}
var file = files.shift ();
fs.readfile (file, function (err, data) {
// обработать данные файла здесь
parsefile (); // после обработки обработайте следующий файл через рекурсивный вызов
});
}
// начать обработку
parsefile ();
Приведенный выше код обработал файлы в массиве, в свою очередь, в качестве примера, введя процесс выполнения контроля кода с помощью рекурсивных средств.
Хорошо применить его к некоторым простым сценариям, таким как: мы можем использовать этот метод, сохранив данные в массиве в базу данных по очереди.
Рекурсивно, некоторые простые проблемы с асинхронным обратным вызовом могут быть решены. Тем не менее, все еще кажется бессильным иметь дело со сложными асинхронными обратными вызовами (такими как синхронизация результатов множественных асинхронных операций).
Великолепная точка: используйте сторонние библиотеки, такие как Async, Q, обещайте обрабатывать асинхронные обратные вызовы
Чтобы лучше обрабатывать вложенные обратные вызовы, вы можете рассмотреть возможность использования некоторых сторонних библиотек, которые специально имеют дело с асинхронными. Конечно, если у вас есть возможность, вы можете написать вспомогательный инструмент для асинхронной обработки самостоятельно.
Наиболее часто используемыми библиотеками для обработки асинхронной обработки являются: асинхронные, Q и обещание. Судя по веб -сайту npmjs.org, Async является самым популярным. Я использовал Async раньше, и это действительно довольно удобно, и различные асинхронные потоки управления обработкой реализованы хорошо.
Мы будем использовать Async для обработки кода, который первоначально считывает два файла одновременно, как показано ниже:
Кода -копия выглядит следующим образом:
var async = require ('async')
, fs = require ('fs');
async.parallel ([[[[[
function (обратный вызов) {
fs.readfile ('/etc/passwd', function (err, data) {
if (err) обратный вызов (err);
обратный вызов (null, data);
});
},
function (обратный вызов) {
fs.readfile ('/etc/passwd2', function (err, data2) {
if (err) обратный вызов (err);
обратный вызов (null, data2);
});
}
],
function (err, результаты) {
// обработать данные данных и данных2 здесь, и содержание каждого файла получено из результатов
});
Через асинхронный модуль процесс асинхронного выполнения может быть хорошо контролируется, что также может решить проблему многоуровневых обратных вызовов. Код более четкий, чем раньше, но он все еще не может быть отделен от функции обратного вызова.
Подумайте об этом, было бы здорово, если бы вы могли справиться с асинхронным без использования функций обратного вызова. Далее, давайте поговорим об использовании новых функций ES6 для достижения этой цели.
Элегантная точка зрения: охватите ES6, замените функции обратного вызова и решите проблему ада обратного вызова
Кстати, Ecmascript Harmony (ES6) представила JS много новых функций. Студенты, которые мало знают об ES6, могут взглянуть на Baidu самостоятельно.
Чтобы использовать новые функции ES6 в Nodejs, вам необходимо использовать v0.11.x или выше.
В этой статье представлено использование функции генератора вместо функций обратного вызова. Не знаете о генераторе? Вы можете проверить это здесь.
Здесь мы используем два модуля CO и Thinkify, и мы используем команду установки NPM для его установки.
Возьмите проблему, упомянутую в начале этой статьи в качестве примера. Пример кода с использованием функции генератора заключается в следующем:
Кода -копия выглядит следующим образом:
var fs = require ('fs')
, co = require ('co')
, thunkify = require ('thinkify');
var readfile = thinkify (fs.readfile);
co (function *() {
var test1 = girt Readfile ('test1.txt');
var test2 = girt Readfile ('test2.txt');
var test = test1.toString () + test2.toString ();
console.log (тест);
}) ();
Также очень просто обрабатывать исключения в коде, просто сделайте это таким образом:
Кода -копия выглядит следующим образом:
пытаться {
var test1 = girt Readfile ('test1.txt');
} catch (e) {
// обрабатывать исключения здесь
}
Этот вид кода гораздо более элегантен? Разве это не здорово, а асинхронно, как написание синхронного кода?
Самая популярная структура для веб -разработки в поле Nodejs - это экспресс. Стоит отметить, что основной участник Express TJ, великого мастера Express, возглавил новую веб -структуру - KOA, которая утверждает, что станет следующим поколением структуры веб -разработки. KOA действительно использует функцию генератора ES6, чтобы помочь нам не попасть в слои обратных вызовов при разработке веб -системы.
Суммировать
Цитируйте предложение от продвижения проекта FIBJS: меньше обратного вызова, больше девушек - меньше обратных вызовов, больше девушек