Переосмысление книги Эдди Османи «Паттерны для масштабируемых JavaScript-приложений»: различия между версиями
Материал из support.qbpro.ru
imported>Supportadmin |
imported>Supportadmin |
||
(не показаны 3 промежуточные версии этого же участника) | |||
Строка 42: | Строка 42: | ||
==Фасад для асинхронного рекурсивного чтения списка фалов в директории== | ==Фасад для асинхронного рекурсивного чтения списка фалов в директории== | ||
Проверено nodejs 0.11.12 Debian wheezy x86_64 | |||
<nowiki>#!/usr/bin/env node | <nowiki>#!/usr/bin/env node | ||
Строка 99: | Строка 101: | ||
dir = dir || this.__dirname; | dir = dir || this.__dirname; | ||
this.reader(dir, ext, this.cbk); | this.reader(dir, ext, this.cbk); | ||
} | } | ||
}; | }; | ||
Строка 126: | Строка 111: | ||
this_module.read_file_list()</nowiki> | this_module.read_file_list()</nowiki> | ||
Замыкание остается в памяти до прекращения процесса. А если это не нужно. Например при запуске кода в виртуальной машине Nodejs. Переделаем фасад для этой цели. | |||
<nowiki>#!/usr/bin/env node | |||
"use strict"; | |||
var fs = require('fs'); | |||
var path = require('path'); | |||
var util = require('util'); | |||
var this_module = { | |||
_private: { | |||
"__dirname": "/home/html_path", | |||
"__extention": /\.html$/i, | |||
"debug": false, | |||
"result": [], | |||
"reader": function (_dirname, extension, callback) { | |||
var results = []; | |||
var that = this; | |||
/*============================*/ | |||
fs.readdir(_dirname, function (err, list) { | |||
if (err) return callback(err); | |||
var pending = list.length; | |||
if (!pending) return callback(null, results); | |||
list.forEach(function (file) { | |||
file = _dirname + '/' + file; | |||
fs.stat(file, function (err, stat) { | |||
if (stat && stat.isDirectory()) { | |||
that.reader(file, extension, function (err, res) { | |||
results = results.concat(res); | |||
if (!--pending) callback(null, results); | |||
}); | |||
} else { | |||
/*выбираем файлы которые соответствуют рег выражению*/ | |||
/*если убрать это условие в массив попадут все файлы*/ | |||
if (extension.test(file)) { | |||
results.push(file); | |||
} | |||
if (!--pending) callback(null, results); | |||
} | |||
}); | |||
}); | |||
}); | |||
/*============================*/ | |||
}, | |||
"cbk": function (err, result) { | |||
if (err) { | |||
console.error(util.inspect(err)); | |||
return; | |||
} | |||
console.log(util.inspect(result)); | |||
return result; | |||
}, | |||
"read": function (dir, ext) { | |||
ext = ext || this.__extention; | |||
dir = dir || this.__dirname; | |||
this.reader(dir, ext, this.cbk); | |||
} | |||
} | |||
}; | |||
function ret() { | |||
return this._private.read(); | |||
} | |||
var bound = ret.bind(this_module); | |||
exports.reader = bound;</nowiki> | |||
Пример использования | |||
<nowiki>#!/usr/bin/env node | |||
"use strict"; | |||
var util = require('util'); | |||
var file_list_reader = require('./mod_async_file_list3').reader; | |||
var file_list = file_list_reader(); | |||
console.log(file_list);</nowiki> |
Текущая версия от 22:24, 1 апреля 2014
Андрей Климов.
Спасибо команде переводчиков за их огромный труд. Сам перевод находится здесь
Итак, скорее всего будет не профессионально, но как есть. (А то сам забудешь и другие не вспомнят)
В главе 9 предложен клевый шаблон проектирования - фасад. Вот его скелет
var module = (function() { var _private = { i: 5, get: function() { console.log('Текущее значение:' + this.i); }, set: function(val) { this.i = val; }, run: function() { console.log('процесс запущен'); }, jump: function() { console.log('резкое изменение'); } }; return { facade: function(args) { _private.set(args.val); _private.get(); if (args.run) { _private.run(); } } } }()); module.facade({run:true, val:10}); // Текущее значение: 10, процесс запущен
Попробуем его применить к практике. Напишу асинхронный модуль, который возвращает список всех файлов в директории и всех вложенных поддиректориях определенным расширением (.html).
Фасад для асинхронного рекурсивного чтения списка фалов в директории
Проверено nodejs 0.11.12 Debian wheezy x86_64
#!/usr/bin/env node "use strict"; var fs = require('fs'); var path = require('path'); var util = require('util'); var this_module = (function () { var _private = { "__dirname": "/home/html_path", "__extention": /\.html$/i, "debug": false, "result": [], "reader": function (_dirname, extension, callback) { var results = []; var that = this; fs.readdir(_dirname, function (err, list) { if (err) return callback(err); var pending = list.length; if (!pending) return callback(null, results); list.forEach(function (file) { file = _dirname + '/' + file; fs.stat(file, function (err, stat) { if (stat && stat.isDirectory()) { that.reader(file, extension, function (err, res) { results = results.concat(res); if (!--pending) callback(null, results); }); } else { /*выбираем файлы которые соответствуют рег выражению*/ /*если убрать это условие в массив попадут все файлы*/ if (extension.test(file)) { results.push(file); } if (!--pending) callback(null, results); } }); }); }); }, "cbk": function (err, result) { if (err) { console.error(util.inspect(err)); return; } console.log(util.inspect(result)); return result; }, "read": function (dir, ext) { ext = ext || this.__extention; dir = dir || this.__dirname; this.reader(dir, ext, this.cbk); } }; return { read_file_list: function (args) { _private.read(); } } }()); this_module.read_file_list()
Замыкание остается в памяти до прекращения процесса. А если это не нужно. Например при запуске кода в виртуальной машине Nodejs. Переделаем фасад для этой цели.
#!/usr/bin/env node "use strict"; var fs = require('fs'); var path = require('path'); var util = require('util'); var this_module = { _private: { "__dirname": "/home/html_path", "__extention": /\.html$/i, "debug": false, "result": [], "reader": function (_dirname, extension, callback) { var results = []; var that = this; /*============================*/ fs.readdir(_dirname, function (err, list) { if (err) return callback(err); var pending = list.length; if (!pending) return callback(null, results); list.forEach(function (file) { file = _dirname + '/' + file; fs.stat(file, function (err, stat) { if (stat && stat.isDirectory()) { that.reader(file, extension, function (err, res) { results = results.concat(res); if (!--pending) callback(null, results); }); } else { /*выбираем файлы которые соответствуют рег выражению*/ /*если убрать это условие в массив попадут все файлы*/ if (extension.test(file)) { results.push(file); } if (!--pending) callback(null, results); } }); }); }); /*============================*/ }, "cbk": function (err, result) { if (err) { console.error(util.inspect(err)); return; } console.log(util.inspect(result)); return result; }, "read": function (dir, ext) { ext = ext || this.__extention; dir = dir || this.__dirname; this.reader(dir, ext, this.cbk); } } }; function ret() { return this._private.read(); } var bound = ret.bind(this_module); exports.reader = bound;
Пример использования
#!/usr/bin/env node "use strict"; var util = require('util'); var file_list_reader = require('./mod_async_file_list3').reader; var file_list = file_list_reader(); console.log(file_list);