진행 단계는 다음과 같았다.
- Steem.js를 이용한 데이터 불러오기
- jQuery를 이용한 템플릿 삽입
- Node.js를 이용한 크롤링
각 단계에서 배운 것들이 있어서 나름 의미가 있었던 부분들. 이 중 Node.js에 대한 부분에 대해 기술해보고자 한다.
steem.js에서 제공되는 API는 주로 asynchornous 함수들이다. 즉,
- steem.api.getDiscussionsByCreated(query, callback_function); 로 제공되는 것이 일반적이다.
아래와 같이 세줄의 코드가 있을 때 1,2,3 순서가 어떻게 출력될지 모르는 상황이 되어버린다.
steem.api.getDiscussionsByCreated(query, function(err, result) { console.log(“1”); } );
steem.api.getDiscussionsByCreated(query, function(err, result) { console.log(“2”); } );
steem.api.getDiscussionsByCreated(query, function(err, result) { console.log(“3”); } );
크롤링을 진행하기 위해서는 각 함수들이 하나의 흐름으로 진행해야만 되는 상태기 때문에 이 함수들이 syncrhonously하게 진행되어야만 했다.
이 때 이용하는 라이브러리가 synchronize.js (http://alexeypetrushin.github.io/synchronize/docs/index.html) 이다.
var sync = require('synchronize');
steem.api.getContent = sync(steem.api.getContent);
steem.api.getAccounts = sync(steem.api.getAccounts);
steem.api.getDiscussionsByHot = sync(steem.api.getDiscussionsByHot);
사용할 함수를 다음과 같이 synchronous 함수로 등록시키고,
sync.fiber(function(){
var data = steem.api.getDiscussionsByCreated(query);
var data2 = steem.api.getDiscussionsByCreated(query2);
var data3 = steem.api.getDiscussionsByCreated(query3);
};
다음과 같이 실행할 경우 순서대로 하나씩 실행하게 된다.
mysql의 경우 Transaction 시작시 다음과 같이 실행하게 되는데,
connection.beginTransaction(function(err) { if (err) { throw err; } connection.query('INSERT INTO posts SET title=?', title, function (error, results, fields) { if (error) { return connection.rollback(function() { throw error; }); } var log = 'Post ' + results.insertId + ' added'; connection.query('INSERT INTO log SET data=?', log, function (error, results, fields) { if (error) { return connection.rollback(function() { throw error; }); } connection.commit(function(err) { if (err) { return connection.rollback(function() { throw err; }); } console.log('success!'); }); }); }); });
Synchronize 를 사용할 경우 에러처리는 다음과 같이 할 수 있다.
try { con.beginTransaction(); } catch(e) { console.log("transaction begin error"); } var truncate_query = 'TRUNCATE `popular_table`'; var result = sync.await(con.query(truncate_query,sync.defer())); for(var i=0;i<values.length;i++) { console.log(i,values.length); var insert_query = "INSERT INTO popular_table SET ? "; //Dictionary에는 set var result = sync.await(con.query(insert_query,[values[i]],sync.defer())); } try { con.commit() } catch(e) { console.log("transaction error"); con.rollback(); }
2 comments