Node.js ворвалось на сервера с невероятной скоростью, ровно с такой же скоростью повергло в шок многих сервер-сайд разработчиков... Многим даже пришлось действительно изучить JavaScript и выйти за уровень jQuery подключателей :), но думаю одной из самых интересных и необычных сторон Node.js в частности и JavaScript в целом это его система колбеков, асинхронных вызовов. Потеряться во вложенности начинающему разработчику раз плюнуть.
Как полностью устроен принцип работы callback в node.js рассказывать не стану. Просто скажу, что первым параметром колбека всегда должен быть err объект или строка ошибки. Если внутри вашей пачки колбеков (в независимом скоупе есть еще череда колбеков), то у внутренних колбеков можно опустить параметр ошибки, т.к. эта пачка будет "видеть" общий для них объект ошибки, который можно смело передать в "выходной" колбек. Чего-то я какой-то замудренной фигни понаписал :), итак перейдем к инструменту который позволяет немного упростить и привести ваш код к более красивому и читаемому виду - это модуль Async, он позволяет навести порядки в ваших стеках колбэков. Итак приступаем. Первым делом добавляем в ваш package.json новую зависимость: "async": "*", после запускаем
npm installИли же можно просто сделать так
npm install --global async
Эта команда установит Async глобально в вашу систему и будет доступен во всех проектах. Итак что нам может предложить Async для Node.js? А предложить он может многое стоит заглянуть для полного списка на его страничку github.org,я же приведу примеры для некоторых из них, и только из раздела control flow а именно:
Series — этот метод позволяет выполнять коллекцию задач по-порядку, и на выходе выполнить какой-нибудь полезный колбек. Этот метод полезен когда важен порядок выполнения, если можно так сказать то этот метод позволит вам "победить" асинхронность ноды:
var async = require('async')
, tasksIndex = [
function (callback) {
// Вымышленный метод который вернет 231
var viewsNumber = models.stat.viewsNumber();
callback(null, viewsNumber);
}
, function (callback) {
// Вымышленный метод который вернет 24
var growFactor = models.stat.growFactor();
callback(null, growFactor);
}
]
, taskNamed = {
viewsNumber: function (callback) {
callback(null, models.stat.viewsNumber());
}
, growFactor: function (callback) {
callback(null, models.stat.growFactor());
}
};
async.series(tasksIndex, function (err, results) {
// Результат будет массивом
console.log(results); // [231, 24]
});
async.series(taskNamed, function (err, results) {
// Результат будет объектом
console.log(results); // {viewsNumber: 231, growFactor: 24}
});
Parallel — а этот метод работает в лучших традициях ноды, не нарушая ее асинхронности, но позволяет отследить конец работы всей пачки задач, т.е. все задачи выполняются параллельно и в конце результаты пробрасываются в финальный колбек. Листинг для этого метода практически ничем не будет отличаться от предыдущего, только надо вызвать не series а parallel
Waterfall — этот метод работает словно цепочка, результаты одной задачи передаются в колбеке следующей задачи, таким образом можно:
Собственно это основные методы по контролю за выполнением колбеков, который упростят работу с ними, для получения более подробной информации советую посетить страничку модуля на Github.
async.waterfall([
function(callback){
callback(null, 'один', 'два');
, }
function(arg1, arg2, callback){
// Тут arg1 равен "один"
// , а arg2 равен "два"
// что соответствует второму и третьему параметру текщего колбека
// , а первый конечно же мы не забыли - это err но в этом случае
// ошибок нет поэтому null
callback(null, 'три');
, }
function(arg1, callback){
// Здесь же arg1 будет равен уже "три"
callback(null, 'Готово');
}
], function (err, result) {
// Сейчас результат будет равен 'Готово'
});
Собственно это основные методы по контролю за выполнением колбеков, который упростят работу с ними, для получения более подробной информации советую посетить страничку модуля на Github.
Спасибо за статью. Немного моих мыслей на тему async JS: http://plutov.by/post/javascript_memory
ОтветитьУдалить