Wordpress DBからカテゴリのディレクトリツリーを作る(2)

公開:2014-08-11 16:34
更新:2017-07-29 13:17
カテゴリ:wordpress,node.js,ブログ,javascript

うまく書けたような

昨日のWordpressカテゴリを元にディレクトリを作成する処理の続き。
非同期処理のためにMySQL接続をうまくクローズできない問題はコードを見直した結果、うまく解決できたような気がする。 js var fs = require('fs'); var zlib = require('zlib'); var Q = require('q'); var dbj = fs.readFileSync('dbinfo.json', 'utf-8'); var dbinfo = JSON.parse(dbj); var home_dir = './blog/'; var nfs = require('node-fs'); var mysql = require('mysql'); var TABLE = 'wp_posts'; //mysqlクライアント作成 var mySQLConn = mysql.createConnection({ user: dbinfo.user, password: dbinfo.password, database: dbinfo.db }); // mysql.mySQLQuery メソッドをプロミスを返すバージョンに変換 var mySQLQuery = Q.nbind(mySQLConn.query, mySQLConn); var qparent = 'select * from wp_terms inner join wp_term_taxonomy on wp_terms.term_id = wp_term_taxonomy.term_id where wp_term_taxonomy.taxonomy = "category" and wp_term_taxonomy.parent = '; function create_category_dir(data) { var qp = qparent + data.id; // 終了検知のためのPromise var defer = Q.defer(); var records = null; // 子カテゴリ処理関数 function create_child_dir() { var tasks = []; for (var i = 0; i < records.length; ++i) { var record = records[i]; var d = { id: record.term_id, name: record.name, slug: record.slug, childs: [], dir: data.dir + '/' + decodeURI(record.slug) }; // 子カテゴリを処理するための再帰呼び出し var pr = create_category_dir(d); // 子処理を完了検知するため配列に保存 tasks.push(pr); data.childs.push(d); } if (!tasks.length) { // リーフ(葉であれば)終了 defer.resolve(); } else { // でなければ子の処理がすべて完了するまで終了を遅延 Q.all(tasks).then(defer.resolve.bind(defer)); } } // クエリする mySQLQuery(qp).then( function (result) { // MYSQLへのクエリ成功 console.log('mySQLQuery クエリ成功'); records = result[0]; // ディレクトリ作成の処理Promiseを返す return Q.nfcall(nfs.mkdir, data.dir, true); }, function (err) { // MYSQLへのクエリ失敗 console.log(err); defer.reject(err); } ).then( // ディレクトリ作成処理が成功 function () { console.log(data.dir); // 子カテゴリのディレクトリを作成する create_child_dir(); }, // ディレクトリ作成処理が失敗 function (err) { if (err.code === 'EEXIST') { // ディレクトリが存在しているのなら処理を続ける console.log(data.dir); create_child_dir(); } else { // それ以外であれば処理を中断する defer.reject(err); } } ); return defer.promise; } var category = { id: 0, name : 'category', slug: 'category' , childs : [], dir : home_dir + 'category' }; create_category_dir(category) .catch(function (err) { // ディレクトリ作成処理失敗 console.log(err); }) .done(function () { // ディレクトリ作成処理完了 console.log('create_category_dir() done.'); // カテゴリーデータをJSON化して表示 console.log(JSON.stringify(category)); // MYSQL接続の終了 mySQLConn.end(); }); Defferedをうまく使って処理終了までresolve()を遅延させることで、終了検知ができるようになった。 非同期処理の処理フローはやっぱり同期処理と違った考え方をしないといけないので、慣れるまでは難しいね。慣れても難しいかもしれないけども。