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
ОтветитьУдалить